From f868dd1bf1320c48a15e14c6da5754227ba2375f Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Thu, 12 Dec 2024 20:45:48 -0600 Subject: [PATCH 001/265] Revert mistaken merge (#209) * feat: include optional dependencies Signed-off-by: Josh Loecker * fix: include taxon id and input format Signed-off-by: Josh Loecker * fix: update requirements based on CC Signed-off-by: Josh Loecker --------- Signed-off-by: Josh Loecker --- main/COMO.ipynb | 313 +++-- main/como/create_context_specific_model.py | 5 +- main/como/rnaseq.py | 5 +- main/como/rnaseq_gen.py | 4 + main/como/rnaseq_preprocess.py | 6 +- pyproject.toml | 34 +- uv.lock | 1336 +++++++++++++++++++- 7 files changed, 1551 insertions(+), 152 deletions(-) diff --git a/main/COMO.ipynb b/main/COMO.ipynb index 8178cd67..073ac978 100644 --- a/main/COMO.ipynb +++ b/main/COMO.ipynb @@ -235,10 +235,65 @@ ] }, { - "metadata": {}, "cell_type": "code", - "outputs": [], - "execution_count": null, + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[32m2024-12-12 20:03:35.823\u001b[0m | \u001b[33m\u001b[1mWARNING \u001b[0m | \u001b[36mcomo.project\u001b[0m:\u001b[36m__init__\u001b[0m:\u001b[36m32\u001b[0m - \u001b[33m\u001b[1m'data_dir' not provided to Config, using /Users/joshl/Projects/COMO/main/data\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:35.824\u001b[0m | \u001b[33m\u001b[1mWARNING \u001b[0m | \u001b[36mcomo.project\u001b[0m:\u001b[36m__init__\u001b[0m:\u001b[36m38\u001b[0m - \u001b[33m\u001b[1m'config_dir' not provided to Config, using /Users/joshl/Projects/COMO/main/data/config_sheets\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:35.824\u001b[0m | \u001b[33m\u001b[1mWARNING \u001b[0m | \u001b[36mcomo.project\u001b[0m:\u001b[36m__init__\u001b[0m:\u001b[36m44\u001b[0m - \u001b[33m\u001b[1m'results_dir' not provided to Config, using /Users/joshl/Projects/COMO/main/data/results\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:35.824\u001b[0m | \u001b[32m\u001b[1mSUCCESS \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36m_handle_context_batch\u001b[0m:\u001b[36m544\u001b[0m - \u001b[32m\u001b[1mFound 1 contexts to process: naiveB\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:35.824\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36m_handle_context_batch\u001b[0m:\u001b[36m552\u001b[0m - \u001b[1mProcessing naiveB\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:35.824\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36m_handle_context_batch\u001b[0m:\u001b[36m559\u001b[0m - \u001b[1mGene info output directory is '/Users/joshl/Projects/COMO/main/data/results/naiveB'\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:36.309\u001b[0m | \u001b[32m\u001b[1mSUCCESS \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36m_create_counts_matrix\u001b[0m:\u001b[36m280\u001b[0m - \u001b[32m\u001b[1mWrote gene count matrix for 'naiveB' at '/Users/joshl/Projects/COMO/main/data/data_matrices/naiveB/gene_counts_matrix_full_naiveB.csv'\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:37.465\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36m_split_counts_matrices\u001b[0m:\u001b[36m462\u001b[0m - \u001b[1mReading gene count matrix file at '/Users/joshl/Projects/COMO/main/data/data_matrices/naiveB/gene_counts_matrix_full_naiveB.csv'\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:37.569\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36m_create_gene_info_file\u001b[0m:\u001b[36m482\u001b[0m - \u001b[1mFetching gene info\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:37.612\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_setup_action\u001b[0m:\u001b[36m193\u001b[0m - \u001b[34m\u001b[1mWill show progress every 6 steps (62 total steps)\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:38.175\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 6 of 62 (with cache) - chunk took 0.6 seconds - running for 0.6 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:38.546\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 12 of 62 (with cache) - chunk took 0.4 seconds - running for 0.9 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:38.807\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 18 of 62 (with cache) - chunk took 0.3 seconds - running for 1.2 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:38.876\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 24 of 62 (with cache) - chunk took 0.1 seconds - running for 1.3 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:38.900\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 30 of 62 (with cache) - chunk took 0.0 seconds - running for 1.3 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:38.939\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 36 of 62 (with cache) - chunk took 0.0 seconds - running for 1.3 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:38.966\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 42 of 62 (with cache) - chunk took 0.0 seconds - running for 1.4 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:38.991\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 48 of 62 (with cache) - chunk took 0.0 seconds - running for 1.4 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:39.019\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 54 of 62 (with cache) - chunk took 0.0 seconds - running for 1.4 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:39.048\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 60 of 62 (with cache) - chunk took 0.0 seconds - running for 1.4 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:39.052\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 62 of 62 (with cache) - chunk took 0.0 seconds - running for 1.4 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:43.431\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_setup_action\u001b[0m:\u001b[36m193\u001b[0m - \u001b[34m\u001b[1mWill show progress every 6 steps (62 total steps)\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:43.976\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 6 of 62 (with cache) - chunk took 0.5 seconds - running for 0.5 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:44.338\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 12 of 62 (with cache) - chunk took 0.4 seconds - running for 0.9 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:44.605\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 18 of 62 (with cache) - chunk took 0.3 seconds - running for 1.2 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:44.671\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 24 of 62 (with cache) - chunk took 0.1 seconds - running for 1.2 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:44.709\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 30 of 62 (with cache) - chunk took 0.0 seconds - running for 1.3 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:44.750\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 36 of 62 (with cache) - chunk took 0.0 seconds - running for 1.3 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:44.778\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 42 of 62 (with cache) - chunk took 0.0 seconds - running for 1.3 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:44.803\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 48 of 62 (with cache) - chunk took 0.0 seconds - running for 1.4 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:44.831\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 54 of 62 (with cache) - chunk took 0.0 seconds - running for 1.4 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:44.858\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 60 of 62 (with cache) - chunk took 0.0 seconds - running for 1.4 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:44.862\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 62 of 62 (with cache) - chunk took 0.0 seconds - running for 1.4 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:49.710\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_setup_action\u001b[0m:\u001b[36m193\u001b[0m - \u001b[34m\u001b[1mWill show progress every 3 steps (37 total steps)\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:54.602\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 3 of 37 (without cache) - chunk took 4.9 seconds - running for 4.9 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:58.056\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 6 of 37 (without cache) - chunk took 3.5 seconds - running for 8.3 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:03:58.746\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 9 of 37 (without cache) - chunk took 0.7 seconds - running for 9.0 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:04:02.708\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 12 of 37 (without cache) - chunk took 4.0 seconds - running for 13.0 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:04:03.024\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 15 of 37 (without cache) - chunk took 0.3 seconds - running for 13.3 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:04:06.776\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 18 of 37 (without cache) - chunk took 3.8 seconds - running for 17.1 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:04:10.314\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 21 of 37 (without cache) - chunk took 3.5 seconds - running for 20.6 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:04:11.271\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 24 of 37 (without cache) - chunk took 1.0 seconds - running for 21.6 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:04:14.453\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 27 of 37 (without cache) - chunk took 3.2 seconds - running for 24.7 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:04:15.415\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 30 of 37 (without cache) - chunk took 1.0 seconds - running for 25.7 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:04:18.397\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 33 of 37 (without cache) - chunk took 3.0 seconds - running for 28.7 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:04:20.117\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 36 of 37 (without cache) - chunk took 1.7 seconds - running for 30.4 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:04:22.557\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 37 of 37 (without cache) - chunk took 2.4 seconds - running for 32.8 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:04:26.377\u001b[0m | \u001b[32m\u001b[1mSUCCESS \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36m_create_gene_info_file\u001b[0m:\u001b[36m526\u001b[0m - \u001b[32m\u001b[1mGene Info file written at '/Users/joshl/Projects/COMO/main/data/gene_info.csv'\u001b[0m\n" + ] + } + ], "source": [ "context_names = \"naiveB\"\n", "taxon_id = \"human\" # accepts integer (bioDBnet taxon id) or \"human\" or \"mouse\"\n", @@ -251,6 +306,7 @@ " \"--context-names\", context_names,\n", " \"--taxon-id\", taxon_id,\n", " \"--mode\", preprocess_mode,\n", + " \"--input-format\", \"Ensembl\"\n", " ]\n", ")\n", "# fmt: on\n", @@ -329,10 +385,44 @@ ] }, { - "metadata": {}, "cell_type": "code", - "outputs": [], - "execution_count": null, + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[32m2024-12-12 20:10:48.752\u001b[0m | \u001b[33m\u001b[1mWARNING \u001b[0m | \u001b[36mcomo.project\u001b[0m:\u001b[36m__init__\u001b[0m:\u001b[36m32\u001b[0m - \u001b[33m\u001b[1m'data_dir' not provided to Config, using /Users/joshl/Projects/COMO/main/data\u001b[0m\n", + "\u001b[32m2024-12-12 20:10:48.752\u001b[0m | \u001b[33m\u001b[1mWARNING \u001b[0m | \u001b[36mcomo.project\u001b[0m:\u001b[36m__init__\u001b[0m:\u001b[36m38\u001b[0m - \u001b[33m\u001b[1m'config_dir' not provided to Config, using /Users/joshl/Projects/COMO/main/data/config_sheets\u001b[0m\n", + "\u001b[32m2024-12-12 20:10:48.752\u001b[0m | \u001b[33m\u001b[1mWARNING \u001b[0m | \u001b[36mcomo.project\u001b[0m:\u001b[36m__init__\u001b[0m:\u001b[36m44\u001b[0m - \u001b[33m\u001b[1m'results_dir' not provided to Config, using /Users/joshl/Projects/COMO/main/data/results\u001b[0m\n", + "\u001b[32m2024-12-12 20:10:48.802\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36m_handle_context_batch\u001b[0m:\u001b[36m79\u001b[0m - \u001b[1mReading config file: /Users/joshl/Projects/COMO/main/data/config_sheets/trnaseq_data_inputs_auto.xlsx\u001b[0m\n", + "\u001b[32m2024-12-12 20:10:48.802\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36m_handle_context_batch\u001b[0m:\u001b[36m82\u001b[0m - \u001b[34m\u001b[1mStarting 'naiveB'\u001b[0m\n", + "\u001b[32m2024-12-12 20:10:48.822\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mcomo.rnaseq\u001b[0m:\u001b[36m_read_counts_matrix\u001b[0m:\u001b[36m198\u001b[0m - \u001b[34m\u001b[1mReading CSV file at '/Users/joshl/Projects/COMO/main/data/data_matrices/naiveB/gene_counts_matrix_total_naiveB.csv'\u001b[0m\n", + "\u001b[32m2024-12-12 20:10:48.861\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_setup_action\u001b[0m:\u001b[36m193\u001b[0m - \u001b[34m\u001b[1mWill show progress every 6 steps (62 total steps)\u001b[0m\n", + "\u001b[32m2024-12-12 20:10:49.449\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 6 of 62 (with cache) - chunk took 0.6 seconds - running for 0.6 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:10:49.826\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 12 of 62 (with cache) - chunk took 0.4 seconds - running for 1.0 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:10:50.083\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 18 of 62 (with cache) - chunk took 0.3 seconds - running for 1.2 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:10:50.158\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 24 of 62 (with cache) - chunk took 0.1 seconds - running for 1.3 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:10:50.183\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 30 of 62 (with cache) - chunk took 0.0 seconds - running for 1.3 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:10:50.225\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 36 of 62 (with cache) - chunk took 0.0 seconds - running for 1.4 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:10:50.252\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 42 of 62 (with cache) - chunk took 0.0 seconds - running for 1.4 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:10:50.279\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 48 of 62 (with cache) - chunk took 0.0 seconds - running for 1.4 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:10:50.307\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 54 of 62 (with cache) - chunk took 0.0 seconds - running for 1.4 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:10:50.336\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 60 of 62 (with cache) - chunk took 0.0 seconds - running for 1.5 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:10:50.353\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 62 of 62 (with cache) - chunk took 0.0 seconds - running for 1.5 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:10:55.137\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mcomo.rnaseq\u001b[0m:\u001b[36mzfpkm_transform\u001b[0m:\u001b[36m420\u001b[0m - \u001b[34m\u001b[1mProcessing 3 samples through zFPKM transform using 9 cores\u001b[0m\n", + "\u001b[32m2024-12-12 20:10:55.137\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mcomo.rnaseq\u001b[0m:\u001b[36mzfpkm_transform\u001b[0m:\u001b[36m421\u001b[0m - \u001b[34m\u001b[1mWill update every 1 steps as this is approximately 10.0% of 3\u001b[0m\n", + "\u001b[32m2024-12-12 20:10:57.217\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mcomo.rnaseq\u001b[0m:\u001b[36mzfpkm_transform\u001b[0m:\u001b[36m454\u001b[0m - \u001b[34m\u001b[1mProcessed 1 of 3 - chunk took 2.0 seconds - running for 2.0 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:10:57.221\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mcomo.rnaseq\u001b[0m:\u001b[36mzfpkm_transform\u001b[0m:\u001b[36m454\u001b[0m - \u001b[34m\u001b[1mProcessed 2 of 3 - chunk took 0.0 seconds - running for 2.0 seconds\u001b[0m\n", + "/Users/joshl/Projects/COMO/main/como/rnaseq.py:491: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n", + " mega_df = pd.concat([mega_df, df], ignore_index=True)\n", + "\u001b[32m2024-12-12 20:10:59.855\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36mcomo.rnaseq\u001b[0m:\u001b[36msave_rnaseq_tests\u001b[0m:\u001b[36m780\u001b[0m - \u001b[1mnaiveB - Found 9492 expressed and 9492 confidently expressed genes\u001b[0m\n", + "\u001b[32m2024-12-12 20:10:59.856\u001b[0m | \u001b[32m\u001b[1mSUCCESS \u001b[0m | \u001b[36mcomo.rnaseq\u001b[0m:\u001b[36msave_rnaseq_tests\u001b[0m:\u001b[36m783\u001b[0m - \u001b[32m\u001b[1mWrote boolean matrix to /Users/joshl/Projects/COMO/main/data/results/naiveB/total/rnaseq_total_naiveB.csv\u001b[0m\n", + "\u001b[32m2024-12-12 20:10:59.856\u001b[0m | \u001b[32m\u001b[1mSUCCESS \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36m_handle_context_batch\u001b[0m:\u001b[36m122\u001b[0m - \u001b[32m\u001b[1mResults saved at '/Users/joshl/Projects/COMO/main/data/results/naiveB/total/rnaseq_total_naiveB.csv'\u001b[0m\n" + ] + } + ], "source": [ "# step 2.2 RNA-seq Analysis for Total RNA-seq library preparation\n", "\n", @@ -343,7 +433,7 @@ "group_ratio_h = 1.0\n", "technique = \"zFPKM\"\n", "minimum_cutoff = -3\n", - "taxon_id = \"human\"\n", + "taxon_id = \"9606\"\n", "\n", "# fmt: off\n", "cmd = \" \".join(\n", @@ -385,10 +475,54 @@ ] }, { - "metadata": {}, "cell_type": "code", - "outputs": [], - "execution_count": null, + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[32m2024-12-12 20:22:51.947\u001b[0m | \u001b[33m\u001b[1mWARNING \u001b[0m | \u001b[36mcomo.project\u001b[0m:\u001b[36m__init__\u001b[0m:\u001b[36m32\u001b[0m - \u001b[33m\u001b[1m'data_dir' not provided to Config, using /Users/joshl/Projects/COMO/main/data\u001b[0m\n", + "\u001b[32m2024-12-12 20:22:51.947\u001b[0m | \u001b[33m\u001b[1mWARNING \u001b[0m | \u001b[36mcomo.project\u001b[0m:\u001b[36m__init__\u001b[0m:\u001b[36m38\u001b[0m - \u001b[33m\u001b[1m'config_dir' not provided to Config, using /Users/joshl/Projects/COMO/main/data/config_sheets\u001b[0m\n", + "\u001b[32m2024-12-12 20:22:51.947\u001b[0m | \u001b[33m\u001b[1mWARNING \u001b[0m | \u001b[36mcomo.project\u001b[0m:\u001b[36m__init__\u001b[0m:\u001b[36m44\u001b[0m - \u001b[33m\u001b[1m'results_dir' not provided to Config, using /Users/joshl/Projects/COMO/main/data/results\u001b[0m\n", + "\u001b[32m2024-12-12 20:22:51.994\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36m_handle_context_batch\u001b[0m:\u001b[36m79\u001b[0m - \u001b[1mReading config file: /Users/joshl/Projects/COMO/main/data/config_sheets/mrnaseq_data_inputs_auto.xlsx\u001b[0m\n", + "\u001b[32m2024-12-12 20:22:51.994\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36m_handle_context_batch\u001b[0m:\u001b[36m82\u001b[0m - \u001b[34m\u001b[1mStarting 'naiveB'\u001b[0m\n", + "\u001b[32m2024-12-12 20:22:52.015\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mcomo.rnaseq\u001b[0m:\u001b[36m_read_counts_matrix\u001b[0m:\u001b[36m198\u001b[0m - \u001b[34m\u001b[1mReading CSV file at '/Users/joshl/Projects/COMO/main/data/data_matrices/naiveB/gene_counts_matrix_mrna_naiveB.csv'\u001b[0m\n", + "\u001b[32m2024-12-12 20:22:52.055\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_setup_action\u001b[0m:\u001b[36m193\u001b[0m - \u001b[34m\u001b[1mWill show progress every 6 steps (62 total steps)\u001b[0m\n", + "\u001b[32m2024-12-12 20:22:52.597\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 6 of 62 (with cache) - chunk took 0.5 seconds - running for 0.5 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:22:52.952\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 12 of 62 (with cache) - chunk took 0.4 seconds - running for 0.9 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:22:53.196\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 18 of 62 (with cache) - chunk took 0.2 seconds - running for 1.1 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:22:53.256\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 24 of 62 (with cache) - chunk took 0.1 seconds - running for 1.2 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:22:53.279\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 30 of 62 (with cache) - chunk took 0.0 seconds - running for 1.2 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:22:53.316\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 36 of 62 (with cache) - chunk took 0.0 seconds - running for 1.3 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:22:53.341\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 42 of 62 (with cache) - chunk took 0.0 seconds - running for 1.3 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:22:53.364\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 48 of 62 (with cache) - chunk took 0.0 seconds - running for 1.3 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:22:53.389\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 54 of 62 (with cache) - chunk took 0.0 seconds - running for 1.3 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:22:53.415\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 60 of 62 (with cache) - chunk took 0.0 seconds - running for 1.4 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:22:53.419\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 62 of 62 (with cache) - chunk took 0.0 seconds - running for 1.4 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:22:58.349\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mcomo.rnaseq\u001b[0m:\u001b[36mzfpkm_transform\u001b[0m:\u001b[36m419\u001b[0m - \u001b[34m\u001b[1mProcessing 4 samples through zFPKM transform using 9 cores\u001b[0m\n", + "\u001b[32m2024-12-12 20:22:58.349\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mcomo.rnaseq\u001b[0m:\u001b[36mzfpkm_transform\u001b[0m:\u001b[36m420\u001b[0m - \u001b[34m\u001b[1mWill update every 1 steps as this is approximately 10.0% of 4\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:00.287\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mcomo.rnaseq\u001b[0m:\u001b[36mzfpkm_transform\u001b[0m:\u001b[36m453\u001b[0m - \u001b[34m\u001b[1mProcessed 1 of 4 - chunk took 1.9 seconds - running for 1.9 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:00.329\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mcomo.rnaseq\u001b[0m:\u001b[36mzfpkm_transform\u001b[0m:\u001b[36m453\u001b[0m - \u001b[34m\u001b[1mProcessed 2 of 4 - chunk took 0.0 seconds - running for 1.9 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:00.329\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mcomo.rnaseq\u001b[0m:\u001b[36mzfpkm_transform\u001b[0m:\u001b[36m453\u001b[0m - \u001b[34m\u001b[1mProcessed 3 of 4 - chunk took 0.0 seconds - running for 1.9 seconds\u001b[0m\n", + "/Users/joshl/Projects/COMO/main/como/rnaseq.py:490: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n", + " mega_df = pd.concat([mega_df, df], ignore_index=True)\n", + "\u001b[32m2024-12-12 20:23:02.582\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mcomo.rnaseq\u001b[0m:\u001b[36mzfpkm_transform\u001b[0m:\u001b[36m419\u001b[0m - \u001b[34m\u001b[1mProcessing 4 samples through zFPKM transform using 9 cores\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:02.582\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mcomo.rnaseq\u001b[0m:\u001b[36mzfpkm_transform\u001b[0m:\u001b[36m420\u001b[0m - \u001b[34m\u001b[1mWill update every 1 steps as this is approximately 10.0% of 4\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:04.422\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mcomo.rnaseq\u001b[0m:\u001b[36mzfpkm_transform\u001b[0m:\u001b[36m453\u001b[0m - \u001b[34m\u001b[1mProcessed 1 of 4 - chunk took 1.8 seconds - running for 1.8 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:04.422\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mcomo.rnaseq\u001b[0m:\u001b[36mzfpkm_transform\u001b[0m:\u001b[36m453\u001b[0m - \u001b[34m\u001b[1mProcessed 2 of 4 - chunk took 0.0 seconds - running for 1.8 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:04.422\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mcomo.rnaseq\u001b[0m:\u001b[36mzfpkm_transform\u001b[0m:\u001b[36m453\u001b[0m - \u001b[34m\u001b[1mProcessed 3 of 4 - chunk took 0.0 seconds - running for 1.8 seconds\u001b[0m\n", + "/Users/joshl/Projects/COMO/main/como/rnaseq.py:490: FutureWarning:\n", + "\n", + "The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n", + "\n", + "\u001b[32m2024-12-12 20:23:06.317\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36mcomo.rnaseq\u001b[0m:\u001b[36msave_rnaseq_tests\u001b[0m:\u001b[36m779\u001b[0m - \u001b[1mnaiveB - Found 3006 expressed and 32 confidently expressed genes\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:06.317\u001b[0m | \u001b[32m\u001b[1mSUCCESS \u001b[0m | \u001b[36mcomo.rnaseq\u001b[0m:\u001b[36msave_rnaseq_tests\u001b[0m:\u001b[36m782\u001b[0m - \u001b[32m\u001b[1mWrote boolean matrix to /Users/joshl/Projects/COMO/main/data/results/naiveB/mrna/rnaseq_mrna_naiveB.csv\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:06.317\u001b[0m | \u001b[32m\u001b[1mSUCCESS \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36m_handle_context_batch\u001b[0m:\u001b[36m122\u001b[0m - \u001b[32m\u001b[1mResults saved at '/Users/joshl/Projects/COMO/main/data/results/naiveB/mrna/rnaseq_mrna_naiveB.csv'\u001b[0m\n" + ] + } + ], "source": [ "mrnaseq_config_file = \"mrnaseq_data_inputs_auto.xlsx\"\n", "rep_ratio = 0.75\n", @@ -397,7 +531,7 @@ "group_ratio_h = 1.0\n", "technique = \"zfpkm\"\n", "minimum_cutoff = -3\n", - "taxon_id = \"human\"\n", + "taxon_id = \"9606\"\n", "\n", "# fmt: off\n", "cmd = \" \".join(\n", @@ -439,10 +573,10 @@ ] }, { - "metadata": {}, "cell_type": "code", - "outputs": [], "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "scrnaseq_config_file = \"scrnaseq_data_inputs_auto.xlsx\"\n", "rep_ratio = 0.75\n", @@ -627,10 +761,49 @@ ] }, { - "metadata": {}, "cell_type": "code", - "outputs": [], - "execution_count": null, + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[32m2024-12-12 20:23:25.719\u001b[0m | \u001b[33m\u001b[1mWARNING \u001b[0m | \u001b[36mcomo.project\u001b[0m:\u001b[36m__init__\u001b[0m:\u001b[36m32\u001b[0m - \u001b[33m\u001b[1m'data_dir' not provided to Config, using /Users/joshl/Projects/COMO/main/data\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:25.719\u001b[0m | \u001b[33m\u001b[1mWARNING \u001b[0m | \u001b[36mcomo.project\u001b[0m:\u001b[36m__init__\u001b[0m:\u001b[36m38\u001b[0m - \u001b[33m\u001b[1m'config_dir' not provided to Config, using /Users/joshl/Projects/COMO/main/data/config_sheets\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:25.719\u001b[0m | \u001b[33m\u001b[1mWARNING \u001b[0m | \u001b[36mcomo.project\u001b[0m:\u001b[36m__init__\u001b[0m:\u001b[36m44\u001b[0m - \u001b[33m\u001b[1m'results_dir' not provided to Config, using /Users/joshl/Projects/COMO/main/data/results\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:25.770\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36m_handle_context_batch\u001b[0m:\u001b[36m505\u001b[0m - \u001b[1mBeginning to merge data within contexts\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:25.770\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36m_handle_context_batch\u001b[0m:\u001b[36m512\u001b[0m - \u001b[34m\u001b[1mUsing zFPKM distribution for merging\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:25.771\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36mcomo.combine_distributions\u001b[0m:\u001b[36m_combine_zscores\u001b[0m:\u001b[36m335\u001b[0m - \u001b[1mWill merge total RNA-seq distributions\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:30.266\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36mcomo.combine_distributions\u001b[0m:\u001b[36m_combine_zscores\u001b[0m:\u001b[36m362\u001b[0m - \u001b[1mWill merge polyA enriched RNA-seq distributions\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:37.761\u001b[0m | \u001b[33m\u001b[1mWARNING \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36m_handle_context_batch\u001b[0m:\u001b[36m549\u001b[0m - \u001b[33m\u001b[1mExpression requirement for naiveB was calculated to be greater than max number of input data sources. Will be force changed to 2 to prevent output from having 0 active genes. Consider lowering the expression requirement or changing the adjustment method.\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:37.761\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36m_merge_xomics\u001b[0m:\u001b[36m345\u001b[0m - \u001b[1mMerging data for naiveB\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:38.084\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.biodbnet.biodbnet\u001b[0m:\u001b[36m_are_nodes_valid\u001b[0m:\u001b[36m40\u001b[0m - \u001b[34m\u001b[1mValidating databases\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:38.084\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_setup_action\u001b[0m:\u001b[36m193\u001b[0m - \u001b[34m\u001b[1mWill show progress every 1 steps (1 total steps)\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:38.739\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_setup_action\u001b[0m:\u001b[36m193\u001b[0m - \u001b[34m\u001b[1mWill show progress every 1 steps (1 total steps)\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:38.745\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_setup_action\u001b[0m:\u001b[36m193\u001b[0m - \u001b[34m\u001b[1mWill show progress every 1 steps (1 total steps)\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:38.750\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.biodbnet.biodbnet\u001b[0m:\u001b[36m_db2db\u001b[0m:\u001b[36m136\u001b[0m - \u001b[34m\u001b[1mDatabases are valid\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:38.750\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.biodbnet.biodbnet\u001b[0m:\u001b[36m_db2db\u001b[0m:\u001b[36m142\u001b[0m - \u001b[34m\u001b[1mGot an input database with a value of 'geneid'\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:38.750\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.biodbnet.biodbnet\u001b[0m:\u001b[36m_db2db\u001b[0m:\u001b[36m143\u001b[0m - \u001b[34m\u001b[1mGot 3 output databases with values of: 'ensemblgeneinfo,geneinfo,genesymbol'\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:38.753\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_setup_action\u001b[0m:\u001b[36m193\u001b[0m - \u001b[34m\u001b[1mWill show progress every 13 steps (138 total steps)\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:43.947\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 13 of 138 (without cache) - chunk took 5.2 seconds - running for 5.2 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:48.238\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 26 of 138 (without cache) - chunk took 4.3 seconds - running for 9.5 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:51.110\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 39 of 138 (without cache) - chunk took 2.9 seconds - running for 12.4 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:55.368\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 52 of 138 (without cache) - chunk took 4.3 seconds - running for 16.6 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:23:58.732\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 65 of 138 (without cache) - chunk took 3.4 seconds - running for 20.0 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:24:03.093\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 78 of 138 (without cache) - chunk took 4.4 seconds - running for 24.3 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:24:07.357\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 91 of 138 (without cache) - chunk took 4.3 seconds - running for 28.6 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:24:10.900\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 104 of 138 (without cache) - chunk took 3.5 seconds - running for 32.1 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:24:14.902\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 117 of 138 (without cache) - chunk took 4.0 seconds - running for 36.1 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:24:19.600\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 130 of 138 (without cache) - chunk took 4.7 seconds - running for 40.8 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:24:21.850\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.fast_http\u001b[0m:\u001b[36m_log_callback\u001b[0m:\u001b[36m150\u001b[0m - \u001b[34m\u001b[1mFinished 138 of 138 (without cache) - chunk took 2.3 seconds - running for 43.1 seconds\u001b[0m\n", + "\u001b[32m2024-12-12 20:24:21.904\u001b[0m | \u001b[34m\u001b[1mDEBUG \u001b[0m | \u001b[36mfast_bioservices.biodbnet.biodbnet\u001b[0m:\u001b[36m_db2db\u001b[0m:\u001b[36m164\u001b[0m - \u001b[34m\u001b[1mReturning dataframe with 34401 rows\u001b[0m\n", + "\u001b[32m2024-12-12 20:24:21.989\u001b[0m | \u001b[32m\u001b[1mSUCCESS \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36m_merge_xomics\u001b[0m:\u001b[36m462\u001b[0m - \u001b[32m\u001b[1mnaiveB: Save to /Users/joshl/Projects/COMO/main/data/results/naiveB/ActiveGenes_naiveB_Merged.csv\n", + "\u001b[0m\n", + "\u001b[32m2024-12-12 20:24:21.991\u001b[0m | \u001b[32m\u001b[1mSUCCESS \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36m\u001b[0m:\u001b[36m857\u001b[0m - \u001b[32m\u001b[1mFinished merging!\u001b[0m\n" + ] + } + ], "source": [ "expression_requirement = 3\n", "requirement_adjust = \"regressive\"\n", @@ -730,7 +903,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 23, "metadata": {}, "outputs": [ { @@ -742,108 +915,28 @@ " Available ModelObjectReader classes can still be loaded using cobamp.wrappers.. An appropriate model \n", " reader can also be created using the get_model_reader function on cobamp.wrappers\n", " warnings.warn(\n", - "\u001B[32m2024-12-04 10:27:00.656\u001B[0m | \u001B[1mINFO \u001B[0m | \u001B[36m__main__\u001B[0m:\u001B[36mcreate_context_specific_model\u001B[0m:\u001B[36m654\u001B[0m - \u001B[1mCreating 'naiveB' model using 'IMAT' reconstruction and 'GUROBI' solver\u001B[0m\n", - "\u001B[32m2024-12-04 10:27:00.656\u001B[0m | \u001B[33m\u001B[1mWARNING \u001B[0m | \u001B[36mcomo.project\u001B[0m:\u001B[36m__init__\u001B[0m:\u001B[36m30\u001B[0m - \u001B[33m\u001B[1m'data_dir' not provided to Config, using /Users/joshl/Projects/COMO/main/data\u001B[0m\n", - "\u001B[32m2024-12-04 10:27:00.656\u001B[0m | \u001B[33m\u001B[1mWARNING \u001B[0m | \u001B[36mcomo.project\u001B[0m:\u001B[36m__init__\u001B[0m:\u001B[36m36\u001B[0m - \u001B[33m\u001B[1m'config_dir' not provided to Config, using /Users/joshl/Projects/COMO/main/data/config_sheets\u001B[0m\n", - "\u001B[32m2024-12-04 10:27:00.656\u001B[0m | \u001B[33m\u001B[1mWARNING \u001B[0m | \u001B[36mcomo.project\u001B[0m:\u001B[36m__init__\u001B[0m:\u001B[36m42\u001B[0m - \u001B[33m\u001B[1m'results_dir' not provided to Config, using /Users/joshl/Projects/COMO/main/data/results\u001B[0m\n", + "\u001b[32m2024-12-12 20:30:56.390\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36mcreate_context_specific_model\u001b[0m:\u001b[36m666\u001b[0m - \u001b[1mCreating 'naiveB' model using 'IMAT' reconstruction and 'GUROBI' solver\u001b[0m\n", + "\u001b[32m2024-12-12 20:30:56.391\u001b[0m | \u001b[33m\u001b[1mWARNING \u001b[0m | \u001b[36mcomo.project\u001b[0m:\u001b[36m__init__\u001b[0m:\u001b[36m32\u001b[0m - \u001b[33m\u001b[1m'data_dir' not provided to Config, using /Users/joshl/Projects/COMO/main/data\u001b[0m\n", + "\u001b[32m2024-12-12 20:30:56.391\u001b[0m | \u001b[33m\u001b[1mWARNING \u001b[0m | \u001b[36mcomo.project\u001b[0m:\u001b[36m__init__\u001b[0m:\u001b[36m38\u001b[0m - \u001b[33m\u001b[1m'config_dir' not provided to Config, using /Users/joshl/Projects/COMO/main/data/config_sheets\u001b[0m\n", + "\u001b[32m2024-12-12 20:30:56.391\u001b[0m | \u001b[33m\u001b[1mWARNING \u001b[0m | \u001b[36mcomo.project\u001b[0m:\u001b[36m__init__\u001b[0m:\u001b[36m44\u001b[0m - \u001b[33m\u001b[1m'results_dir' not provided to Config, using /Users/joshl/Projects/COMO/main/data/results\u001b[0m\n", "Set parameter WLSAccessID\n", "Set parameter WLSSecret\n", "Set parameter LicenseID to value 898845\n", "Academic license 898845 - for non-commercial use only - registered to jl___@huskers.unl.edu\n", - "No defined compartments in model GeneralModelUpdatedV2. Compartments will be deduced heuristically using regular expressions.\n", - "Using regular expression found the following compartments:c, e, g, i, l, m, n, r, x\n", - "/Users/joshl/Projects/COMO/main/como/utils.py:154: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '['1' '10' '100' ... '9992' '9993' '9997']' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.\n", + "/Users/joshl/Projects/COMO/main/como/utils.py:158: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future error of pandas. Value '['1' '10' '100' ... '9992' '9993' '9997']' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.\n", " expression_data.loc[:, \"entrez_gene_id\"] = expression_data[\"entrez_gene_id\"].astype(str)\n", - "\u001B[32m2024-12-04 10:27:04.957\u001B[0m | \u001B[1mINFO \u001B[0m | \u001B[36m__main__\u001B[0m:\u001B[36m_map_expression_to_reaction\u001B[0m:\u001B[36m391\u001B[0m - \u001B[1mMapped gene expression to reactions, found 2806 error(s).\u001B[0m\n", - "\u001B[32m2024-12-04 10:27:04.959\u001B[0m | \u001B[33m\u001B[1mWARNING \u001B[0m | \u001B[36m__main__\u001B[0m:\u001B[36m_build_model\u001B[0m:\u001B[36m468\u001B[0m - \u001B[33m\u001B[1mThe force reaction 'ICDH_m' was not found in the general reference_model. Check BiGG, or the relevant database for your general reference_model, for synonyms.\u001B[0m\n", - "\u001B[32m2024-12-04 10:27:04.959\u001B[0m | \u001B[33m\u001B[1mWARNING \u001B[0m | \u001B[36m__main__\u001B[0m:\u001B[36m_build_model\u001B[0m:\u001B[36m468\u001B[0m - \u001B[33m\u001B[1mThe force reaction 'CATC140_c' was not found in the general reference_model. Check BiGG, or the relevant database for your general reference_model, for synonyms.\u001B[0m\n", - "Read LP format model from file /var/folders/6s/9l9z74v90tn8lprrp7fchb9w0000gn/T/tmprdfbwfb2.lp\n", + "\u001b[32m2024-12-12 20:31:00.773\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36m_map_expression_to_reaction\u001b[0m:\u001b[36m400\u001b[0m - \u001b[1mMapped gene expression to reactions, found 2806 error(s).\u001b[0m\n", + "\u001b[32m2024-12-12 20:31:00.774\u001b[0m | \u001b[33m\u001b[1mWARNING \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36m_build_model\u001b[0m:\u001b[36m477\u001b[0m - \u001b[33m\u001b[1mThe force reaction 'ICDH_m' was not found in the general reference_model. Check BiGG, or the relevant database for your general reference_model, for synonyms.\u001b[0m\n", + "\u001b[32m2024-12-12 20:31:00.774\u001b[0m | \u001b[33m\u001b[1mWARNING \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36m_build_model\u001b[0m:\u001b[36m477\u001b[0m - \u001b[33m\u001b[1mThe force reaction 'CATC140_c' was not found in the general reference_model. Check BiGG, or the relevant database for your general reference_model, for synonyms.\u001b[0m\n", + "Read LP format model from file /var/folders/6s/9l9z74v90tn8lprrp7fchb9w0000gn/T/tmpvza88s5l.lp\n", "Reading time = 0.02 seconds\n", ": 5837 rows, 21220 columns, 81018 nonzeros\n", "/Users/joshl/Projects/COMO/.venv/lib/python3.10/site-packages/cobra/core/group.py:147: UserWarning: need to pass in a list\n", " warn(\"need to pass in a list\")\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "Error encountered trying to >.\n", - "LibSBML error code -3: The requested action could not be performed. This can occur in a variety of contexts, such as passing a null object as a parameter in a situation where it does not make sense to permit a null object.\n", - "\u001B[32m2024-12-04 10:27:45.905\u001B[0m | \u001B[32m\u001B[1mSUCCESS \u001B[0m | \u001B[36m__main__\u001B[0m:\u001B[36mcreate_context_specific_model\u001B[0m:\u001B[36m690\u001B[0m - \u001B[32m\u001B[1mSaved output file to /Users/joshl/Projects/COMO/main/data/results/naiveB\u001B[0m\n", - "\u001B[32m2024-12-04 10:27:45.905\u001B[0m | \u001B[1mINFO \u001B[0m | \u001B[36m__main__\u001B[0m:\u001B[36mcreate_context_specific_model\u001B[0m:\u001B[36m691\u001B[0m - \u001B[1mNumber of Genes: 1,477\u001B[0m\n", - "\u001B[32m2024-12-04 10:27:45.905\u001B[0m | \u001B[1mINFO \u001B[0m | \u001B[36m__main__\u001B[0m:\u001B[36mcreate_context_specific_model\u001B[0m:\u001B[36m692\u001B[0m - \u001B[1mNumber of Metabolites: 3,204\u001B[0m\n", - "\u001B[32m2024-12-04 10:27:45.905\u001B[0m | \u001B[1mINFO \u001B[0m | \u001B[36m__main__\u001B[0m:\u001B[36mcreate_context_specific_model\u001B[0m:\u001B[36m693\u001B[0m - \u001B[1mNumber of Reactions: 5,263\u001B[0m\n", + "\u001b[32m2024-12-12 20:31:43.474\u001b[0m | \u001b[32m\u001b[1mSUCCESS \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36mcreate_context_specific_model\u001b[0m:\u001b[36m702\u001b[0m - \u001b[32m\u001b[1mSaved output file to /Users/joshl/Projects/COMO/main/data/results/naiveB\u001b[0m\n", + "\u001b[32m2024-12-12 20:31:43.475\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36mcreate_context_specific_model\u001b[0m:\u001b[36m703\u001b[0m - \u001b[1mNumber of Genes: 1,477\u001b[0m\n", + "\u001b[32m2024-12-12 20:31:43.475\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36mcreate_context_specific_model\u001b[0m:\u001b[36m704\u001b[0m - \u001b[1mNumber of Metabolites: 3,204\u001b[0m\n", + "\u001b[32m2024-12-12 20:31:43.475\u001b[0m | \u001b[1mINFO \u001b[0m | \u001b[36m__main__\u001b[0m:\u001b[36mcreate_context_specific_model\u001b[0m:\u001b[36m705\u001b[0m - \u001b[1mNumber of Reactions: 5,263\u001b[0m\n", "Warning: environment still referenced so free is deferred (Continue to use WLS)\n" ] } diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index f6ac8b91..c072404c 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -340,11 +340,11 @@ def _build_with_imat( def _build_with_tinit(cobra_model: cobra.Model, s_matrix, lb, ub, expr_vector, solver, idx_force) -> Model: properties = tINITProperties( reactions_scores=expr_vector, - solver=solver, essential_reactions=idx_force, production_weight=0.0, allow_excretion=False, no_reverse_loops=True, + solver=solver, ) algorithm = tINIT(s_matrix, lb, ub, properties) algorithm.preprocessing() @@ -565,7 +565,6 @@ def _collect_boundary_reactions(path: Path) -> _BoundaryReactions: for column in df.columns: if column not in [ "boundary", - "reaction", "abbreviation", "compartment", "minimum reaction rate", @@ -577,7 +576,7 @@ def _collect_boundary_reactions(path: Path) -> _BoundaryReactions: ) reactions: list[str] = [""] * len(df) - boundary_type: list[str] = df["reaction"].tolist() + boundary_type: list[str] = df["boundary"].tolist() reaction_abbreviation: list[str] = df["abbreviation"].tolist() reaction_compartment: list[str] = df["compartment"].tolist() lower_bound = df["minimum reaction rate"].tolist() diff --git a/main/como/rnaseq.py b/main/como/rnaseq.py index 055078fc..8afa9779 100644 --- a/main/como/rnaseq.py +++ b/main/como/rnaseq.py @@ -297,8 +297,8 @@ def calculate_tpm(metrics: NamedMetrics) -> NamedMetrics: def calculate_fpkm(metrics: NamedMetrics) -> NamedMetrics: """Calculate the Fragments Per Kilobase of transcript per Million mapped reads (FPKM) for each sample in the metrics dictionary.""" # noqa: E501 - matrix_values = [] for study in metrics: + matrix_values = [] for sample in range(metrics[study].num_samples): layout = metrics[study].layout[sample] count_matrix: npt.NDArray = metrics[study].count_matrix.iloc[:, sample].values @@ -311,7 +311,7 @@ def calculate_fpkm(metrics: NamedMetrics) -> NamedMetrics: case LayoutMethod.paired_end: # FPKM mean_fragment_lengths = metrics[study].fragment_lengths[sample] # Ensure non-negative value - effective_length = [max(0, size - (mean_fragment_lengths + 1)) for size in gene_size] + effective_length = [max(1e-9, size - (mean_fragment_lengths + 1)) for size in gene_size] n = count_matrix.sum() fpkm = ((count_matrix + 1) * 1e9) / (np.array(effective_length) * n) matrix_values.append(fpkm) @@ -326,7 +326,6 @@ def calculate_fpkm(metrics: NamedMetrics) -> NamedMetrics: fpkm_matrix = pd.DataFrame(matrix_values).T # Transpose is needed because values were appended as rows fpkm_matrix = fpkm_matrix[~pd.isna(fpkm_matrix)] metrics[study].normalization_matrix = fpkm_matrix - metrics[study].normalization_matrix.columns = metrics[study].count_matrix.columns return metrics diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 55234919..69b9315f 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -99,6 +99,10 @@ async def _handle_context_batch( ) rnaseq_output_filepath.parent.mkdir(parents=True, exist_ok=True) + write_zfpkm_png_filepath = write_zfpkm_png_filepath or Path( + f"data/results/{context_name}/zfpkm_{prep.value}_{context_name}.png" + ) + await save_rnaseq_tests( context_name=context_name, counts_matrix_filepath=rnaseq_input_filepath, diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index c522f0f1..f85c3f4f 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -351,7 +351,7 @@ async def _create_config_df(context_name: str) -> pd.DataFrame: # noqa: C901 f"this should be defined by user if using zFPKM or rnaseq_gen.py will not run" ) elif len(layout_files) == 1: - with layout_files[0].open("w") as file: + with layout_files[0].open("r") as file: layout = file.read().strip() elif len(layout_files) > 1: raise ValueError( @@ -367,7 +367,7 @@ async def _create_config_df(context_name: str) -> pd.DataFrame: # noqa: C901 f"infer the strandedness when writing the counts matrix" ) elif len(strand_files) == 1: - with strand_files[0].open("w") as file: + with strand_files[0].open("r") as file: strand = file.read().strip() elif len(strand_files) > 1: raise ValueError( @@ -379,7 +379,7 @@ async def _create_config_df(context_name: str) -> pd.DataFrame: # noqa: C901 if len(prep_files) == 0: logger.warning(f"No prep file found for {label}, assuming 'total' as in Total RNA library preparation") elif len(prep_files) == 1: - with prep_files[0].open("w") as file: + with prep_files[0].open("r") as file: prep = file.read().strip().lower() if prep not in ["total", "mrna"]: raise ValueError(f"Prep method must be either 'total' or 'mrna' for {label}") diff --git a/pyproject.toml b/pyproject.toml index 2f4fdb2f..155641be 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,7 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + [project] name = "COMO" dynamic = ["version"] @@ -5,7 +9,6 @@ requires-python = ">=3.10,<3.13" dependencies = [ "cobra>=0.28.0", "fast-bioservices>=0.3.9", - "gurobipy>=11.0", "kaleido==0.2.1", "loguru>=0.7.2", "pandas>=1.3.5", @@ -21,9 +24,20 @@ dependencies = [ "cobamp@git+https://github.com/JoshLoecker/cobamp@master", ] -[build-system] -requires = ["hatchling"] -build-backend = "hatchling.build" +[project.optional-dependencies] +gurobi = [ "gurobipy>=10.0.0" ] +interactive = [ + "jupyterlab>=4.0.0", + "ipython>=7.0.0" +] +dev = [ + "commitlint>=1.3.0", + "pytest-asyncio>=0.24.0", + "pytest>=8.0.0", + "ruff>=0.8.0", + "hypothesis>=6.122.1", + "pytest-cov>=6.0.0", +] [tool.hatch.version] path = "main/como/__init__.py" @@ -35,14 +49,4 @@ packages = ["main/como"] allow-direct-references = true [tool.pytest.ini_options] -pythonpath = [ "main/src" ] - -[tool.uv] -dev-dependencies = [ - "commitlint>=1.3.0", - "pytest-asyncio>=0.24.0", - "pytest>=8.3.3", - "ruff>=0.8.0", - "hypothesis>=6.122.1", - "pytest-cov>=6.0.0", -] +pythonpath = [ "main/src" ] \ No newline at end of file diff --git a/uv.lock b/uv.lock index f090d8cc..a58d3e57 100644 --- a/uv.lock +++ b/uv.lock @@ -78,6 +78,48 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3b/00/2344469e2084fb287c2e0b57b72910309874c3245463acd6cf5e3db69324/appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128", size = 9566 }, ] +[[package]] +name = "appnope" +version = "0.1.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/35/5d/752690df9ef5b76e169e68d6a129fa6d08a7100ca7f754c89495db3c6019/appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee", size = 4170 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c", size = 4321 }, +] + +[[package]] +name = "argon2-cffi" +version = "23.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "argon2-cffi-bindings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/31/fa/57ec2c6d16ecd2ba0cf15f3c7d1c3c2e7b5fcb83555ff56d7ab10888ec8f/argon2_cffi-23.1.0.tar.gz", hash = "sha256:879c3e79a2729ce768ebb7d36d4609e3a78a4ca2ec3a9f12286ca057e3d0db08", size = 42798 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a4/6a/e8a041599e78b6b3752da48000b14c8d1e8a04ded09c88c714ba047f34f5/argon2_cffi-23.1.0-py3-none-any.whl", hash = "sha256:c670642b78ba29641818ab2e68bd4e6a78ba53b7eff7b4c3815ae16abf91c7ea", size = 15124 }, +] + +[[package]] +name = "argon2-cffi-bindings" +version = "21.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b9/e9/184b8ccce6683b0aa2fbb7ba5683ea4b9c5763f1356347f1312c32e3c66e/argon2-cffi-bindings-21.2.0.tar.gz", hash = "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3", size = 1779911 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d4/13/838ce2620025e9666aa8f686431f67a29052241692a3dd1ae9d3692a89d3/argon2_cffi_bindings-21.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367", size = 29658 }, + { url = "https://files.pythonhosted.org/packages/b3/02/f7f7bb6b6af6031edb11037639c697b912e1dea2db94d436e681aea2f495/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9524464572e12979364b7d600abf96181d3541da11e23ddf565a32e70bd4dc0d", size = 80583 }, + { url = "https://files.pythonhosted.org/packages/ec/f7/378254e6dd7ae6f31fe40c8649eea7d4832a42243acaf0f1fff9083b2bed/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b746dba803a79238e925d9046a63aa26bf86ab2a2fe74ce6b009a1c3f5c8f2ae", size = 86168 }, + { url = "https://files.pythonhosted.org/packages/74/f6/4a34a37a98311ed73bb80efe422fed95f2ac25a4cacc5ae1d7ae6a144505/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58ed19212051f49a523abb1dbe954337dc82d947fb6e5a0da60f7c8471a8476c", size = 82709 }, + { url = "https://files.pythonhosted.org/packages/74/2b/73d767bfdaab25484f7e7901379d5f8793cccbb86c6e0cbc4c1b96f63896/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:bd46088725ef7f58b5a1ef7ca06647ebaf0eb4baff7d1d0d177c6cc8744abd86", size = 83613 }, + { url = "https://files.pythonhosted.org/packages/4f/fd/37f86deef67ff57c76f137a67181949c2d408077e2e3dd70c6c42912c9bf/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_i686.whl", hash = "sha256:8cd69c07dd875537a824deec19f978e0f2078fdda07fd5c42ac29668dda5f40f", size = 84583 }, + { url = "https://files.pythonhosted.org/packages/6f/52/5a60085a3dae8fded8327a4f564223029f5f54b0cb0455a31131b5363a01/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f1152ac548bd5b8bcecfb0b0371f082037e47128653df2e8ba6e914d384f3c3e", size = 88475 }, + { url = "https://files.pythonhosted.org/packages/8b/95/143cd64feb24a15fa4b189a3e1e7efbaeeb00f39a51e99b26fc62fbacabd/argon2_cffi_bindings-21.2.0-cp36-abi3-win32.whl", hash = "sha256:603ca0aba86b1349b147cab91ae970c63118a0f30444d4bc80355937c950c082", size = 27698 }, + { url = "https://files.pythonhosted.org/packages/37/2c/e34e47c7dee97ba6f01a6203e0383e15b60fb85d78ac9a15cd066f6fe28b/argon2_cffi_bindings-21.2.0-cp36-abi3-win_amd64.whl", hash = "sha256:b2ef1c30440dbbcba7a5dc3e319408b59676e2e039e2ae11a8775ecf482b192f", size = 30817 }, + { url = "https://files.pythonhosted.org/packages/5a/e4/bf8034d25edaa495da3c8a3405627d2e35758e44ff6eaa7948092646fdcc/argon2_cffi_bindings-21.2.0-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e415e3f62c8d124ee16018e491a009937f8cf7ebf5eb430ffc5de21b900dad93", size = 53104 }, +] + [[package]] name = "array-api-compat" version = "1.9" @@ -87,6 +129,40 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/45/78/17985eac75d04c30f8cc375e4400e20b0787dc4a1c853a8fe9fad7932f55/array_api_compat-1.9-py3-none-any.whl", hash = "sha256:76db63c2d2461ba0e86b920c8b087f0a1617eb14de3ec29fe6811eeecad9c5e8", size = 49489 }, ] +[[package]] +name = "arrow" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "python-dateutil" }, + { name = "types-python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2e/00/0f6e8fcdb23ea632c866620cc872729ff43ed91d284c866b515c6342b173/arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85", size = 131960 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/ed/e97229a566617f2ae958a6b13e7cc0f585470eac730a73e9e82c32a3cdd2/arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80", size = 66419 }, +] + +[[package]] +name = "asttokens" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4a/e7/82da0a03e7ba5141f05cce0d302e6eed121ae055e0456ca228bf693984bc/asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7", size = 61978 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/25/8a/c46dcc25341b5bce5472c718902eb3d38600a903b14fa6aeecef3f21a46f/asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2", size = 26918 }, +] + +[[package]] +name = "async-lru" +version = "2.0.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/80/e2/2b4651eff771f6fd900d233e175ddc5e2be502c7eb62c0c42f975c6d36cd/async-lru-2.0.4.tar.gz", hash = "sha256:b8a59a5df60805ff63220b2a0c5b5393da5521b113cd5465a44eb037d81a5627", size = 10019 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fa/9f/3c3503693386c4b0f245eaf5ca6198e3b28879ca0a40bde6b0e319793453/async_lru-2.0.4-py3-none-any.whl", hash = "sha256:ff02944ce3c288c5be660c42dbcca0742b32c3b279d6dceda655190240b99224", size = 6111 }, +] + [[package]] name = "attrs" version = "24.2.0" @@ -96,6 +172,39 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6a/21/5b6702a7f963e95456c0de2d495f67bf5fd62840ac655dc451586d23d39a/attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2", size = 63001 }, ] +[[package]] +name = "babel" +version = "2.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2a/74/f1bc80f23eeba13393b7222b11d95ca3af2c1e28edca18af487137eefed9/babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316", size = 9348104 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/20/bc79bc575ba2e2a7f70e8a1155618bb1301eaa5132a8271373a6903f73f8/babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b", size = 9587599 }, +] + +[[package]] +name = "beautifulsoup4" +version = "4.12.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "soupsieve" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/ca/824b1195773ce6166d388573fc106ce56d4a805bd7427b624e063596ec58/beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051", size = 581181 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/fe/e8c672695b37eecc5cbf43e1d0638d88d66ba3a44c4d321c796f4e59167f/beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed", size = 147925 }, +] + +[[package]] +name = "bleach" +version = "6.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "webencodings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/76/9a/0e33f5054c54d349ea62c277191c020c2d6ef1d65ab2cb1993f91ec846d1/bleach-6.2.0.tar.gz", hash = "sha256:123e894118b8a599fd80d3ec1a6d4cc7ce4e5882b1317a7e1ba69b56e95f991f", size = 203083 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fc/55/96142937f66150805c25c4d0f31ee4132fd33497753400734f9dfdcbdc66/bleach-6.2.0-py3-none-any.whl", hash = "sha256:117d9c6097a7c3d22fd578fcd8d35ff1e125df6736f554da4e432fdd63f31e5e", size = 163406 }, +] + [[package]] name = "boolean-py" version = "4.0" @@ -114,10 +223,110 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", size = 167321 }, ] +[[package]] +name = "cffi" +version = "1.17.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycparser" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/90/07/f44ca684db4e4f08a3fdc6eeb9a0d15dc6883efc7b8c90357fdbf74e186c/cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14", size = 182191 }, + { url = "https://files.pythonhosted.org/packages/08/fd/cc2fedbd887223f9f5d170c96e57cbf655df9831a6546c1727ae13fa977a/cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67", size = 178592 }, + { url = "https://files.pythonhosted.org/packages/de/cc/4635c320081c78d6ffc2cab0a76025b691a91204f4aa317d568ff9280a2d/cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382", size = 426024 }, + { url = "https://files.pythonhosted.org/packages/b6/7b/3b2b250f3aab91abe5f8a51ada1b717935fdaec53f790ad4100fe2ec64d1/cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702", size = 448188 }, + { url = "https://files.pythonhosted.org/packages/d3/48/1b9283ebbf0ec065148d8de05d647a986c5f22586b18120020452fff8f5d/cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3", size = 455571 }, + { url = "https://files.pythonhosted.org/packages/40/87/3b8452525437b40f39ca7ff70276679772ee7e8b394934ff60e63b7b090c/cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6", size = 436687 }, + { url = "https://files.pythonhosted.org/packages/8d/fb/4da72871d177d63649ac449aec2e8a29efe0274035880c7af59101ca2232/cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17", size = 446211 }, + { url = "https://files.pythonhosted.org/packages/ab/a0/62f00bcb411332106c02b663b26f3545a9ef136f80d5df746c05878f8c4b/cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8", size = 461325 }, + { url = "https://files.pythonhosted.org/packages/36/83/76127035ed2e7e27b0787604d99da630ac3123bfb02d8e80c633f218a11d/cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e", size = 438784 }, + { url = "https://files.pythonhosted.org/packages/21/81/a6cd025db2f08ac88b901b745c163d884641909641f9b826e8cb87645942/cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be", size = 461564 }, + { url = "https://files.pythonhosted.org/packages/f8/fe/4d41c2f200c4a457933dbd98d3cf4e911870877bd94d9656cc0fcb390681/cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c", size = 171804 }, + { url = "https://files.pythonhosted.org/packages/d1/b6/0b0f5ab93b0df4acc49cae758c81fe4e5ef26c3ae2e10cc69249dfd8b3ab/cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15", size = 181299 }, + { url = "https://files.pythonhosted.org/packages/6b/f4/927e3a8899e52a27fa57a48607ff7dc91a9ebe97399b357b85a0c7892e00/cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401", size = 182264 }, + { url = "https://files.pythonhosted.org/packages/6c/f5/6c3a8efe5f503175aaddcbea6ad0d2c96dad6f5abb205750d1b3df44ef29/cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf", size = 178651 }, + { url = "https://files.pythonhosted.org/packages/94/dd/a3f0118e688d1b1a57553da23b16bdade96d2f9bcda4d32e7d2838047ff7/cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4", size = 445259 }, + { url = "https://files.pythonhosted.org/packages/2e/ea/70ce63780f096e16ce8588efe039d3c4f91deb1dc01e9c73a287939c79a6/cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", size = 469200 }, + { url = "https://files.pythonhosted.org/packages/1c/a0/a4fa9f4f781bda074c3ddd57a572b060fa0df7655d2a4247bbe277200146/cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", size = 477235 }, + { url = "https://files.pythonhosted.org/packages/62/12/ce8710b5b8affbcdd5c6e367217c242524ad17a02fe5beec3ee339f69f85/cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", size = 459721 }, + { url = "https://files.pythonhosted.org/packages/ff/6b/d45873c5e0242196f042d555526f92aa9e0c32355a1be1ff8c27f077fd37/cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", size = 467242 }, + { url = "https://files.pythonhosted.org/packages/1a/52/d9a0e523a572fbccf2955f5abe883cfa8bcc570d7faeee06336fbd50c9fc/cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", size = 477999 }, + { url = "https://files.pythonhosted.org/packages/44/74/f2a2460684a1a2d00ca799ad880d54652841a780c4c97b87754f660c7603/cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f", size = 454242 }, + { url = "https://files.pythonhosted.org/packages/f8/4a/34599cac7dfcd888ff54e801afe06a19c17787dfd94495ab0c8d35fe99fb/cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b", size = 478604 }, + { url = "https://files.pythonhosted.org/packages/34/33/e1b8a1ba29025adbdcda5fb3a36f94c03d771c1b7b12f726ff7fef2ebe36/cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655", size = 171727 }, + { url = "https://files.pythonhosted.org/packages/3d/97/50228be003bb2802627d28ec0627837ac0bf35c90cf769812056f235b2d1/cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0", size = 181400 }, + { url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178 }, + { url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840 }, + { url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803 }, + { url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850 }, + { url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729 }, + { url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256 }, + { url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424 }, + { url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568 }, + { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736 }, + { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448 }, + { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976 }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/4f/e1808dc01273379acc506d18f1504eb2d299bd4131743b9fc54d7be4df1e/charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", size = 106620 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/8b/825cc84cf13a28bfbcba7c416ec22bf85a9584971be15b21dd8300c65b7f/charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6", size = 196363 }, + { url = "https://files.pythonhosted.org/packages/23/81/d7eef6a99e42c77f444fdd7bc894b0ceca6c3a95c51239e74a722039521c/charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b", size = 125639 }, + { url = "https://files.pythonhosted.org/packages/21/67/b4564d81f48042f520c948abac7079356e94b30cb8ffb22e747532cf469d/charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99", size = 120451 }, + { url = "https://files.pythonhosted.org/packages/c2/72/12a7f0943dd71fb5b4e7b55c41327ac0a1663046a868ee4d0d8e9c369b85/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca", size = 140041 }, + { url = "https://files.pythonhosted.org/packages/67/56/fa28c2c3e31217c4c52158537a2cf5d98a6c1e89d31faf476c89391cd16b/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d", size = 150333 }, + { url = "https://files.pythonhosted.org/packages/f9/d2/466a9be1f32d89eb1554cf84073a5ed9262047acee1ab39cbaefc19635d2/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7", size = 142921 }, + { url = "https://files.pythonhosted.org/packages/f8/01/344ec40cf5d85c1da3c1f57566c59e0c9b56bcc5566c08804a95a6cc8257/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3", size = 144785 }, + { url = "https://files.pythonhosted.org/packages/73/8b/2102692cb6d7e9f03b9a33a710e0164cadfce312872e3efc7cfe22ed26b4/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907", size = 146631 }, + { url = "https://files.pythonhosted.org/packages/d8/96/cc2c1b5d994119ce9f088a9a0c3ebd489d360a2eb058e2c8049f27092847/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b", size = 140867 }, + { url = "https://files.pythonhosted.org/packages/c9/27/cde291783715b8ec30a61c810d0120411844bc4c23b50189b81188b273db/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912", size = 149273 }, + { url = "https://files.pythonhosted.org/packages/3a/a4/8633b0fc1a2d1834d5393dafecce4a1cc56727bfd82b4dc18fc92f0d3cc3/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95", size = 152437 }, + { url = "https://files.pythonhosted.org/packages/64/ea/69af161062166b5975ccbb0961fd2384853190c70786f288684490913bf5/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e", size = 150087 }, + { url = "https://files.pythonhosted.org/packages/3b/fd/e60a9d9fd967f4ad5a92810138192f825d77b4fa2a557990fd575a47695b/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe", size = 145142 }, + { url = "https://files.pythonhosted.org/packages/6d/02/8cb0988a1e49ac9ce2eed1e07b77ff118f2923e9ebd0ede41ba85f2dcb04/charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc", size = 94701 }, + { url = "https://files.pythonhosted.org/packages/d6/20/f1d4670a8a723c46be695dff449d86d6092916f9e99c53051954ee33a1bc/charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749", size = 102191 }, + { url = "https://files.pythonhosted.org/packages/9c/61/73589dcc7a719582bf56aae309b6103d2762b526bffe189d635a7fcfd998/charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", size = 193339 }, + { url = "https://files.pythonhosted.org/packages/77/d5/8c982d58144de49f59571f940e329ad6e8615e1e82ef84584c5eeb5e1d72/charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", size = 124366 }, + { url = "https://files.pythonhosted.org/packages/bf/19/411a64f01ee971bed3231111b69eb56f9331a769072de479eae7de52296d/charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", size = 118874 }, + { url = "https://files.pythonhosted.org/packages/4c/92/97509850f0d00e9f14a46bc751daabd0ad7765cff29cdfb66c68b6dad57f/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", size = 138243 }, + { url = "https://files.pythonhosted.org/packages/e2/29/d227805bff72ed6d6cb1ce08eec707f7cfbd9868044893617eb331f16295/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", size = 148676 }, + { url = "https://files.pythonhosted.org/packages/13/bc/87c2c9f2c144bedfa62f894c3007cd4530ba4b5351acb10dc786428a50f0/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", size = 141289 }, + { url = "https://files.pythonhosted.org/packages/eb/5b/6f10bad0f6461fa272bfbbdf5d0023b5fb9bc6217c92bf068fa5a99820f5/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", size = 142585 }, + { url = "https://files.pythonhosted.org/packages/3b/a0/a68980ab8a1f45a36d9745d35049c1af57d27255eff8c907e3add84cf68f/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5", size = 144408 }, + { url = "https://files.pythonhosted.org/packages/d7/a1/493919799446464ed0299c8eef3c3fad0daf1c3cd48bff9263c731b0d9e2/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", size = 139076 }, + { url = "https://files.pythonhosted.org/packages/fb/9d/9c13753a5a6e0db4a0a6edb1cef7aee39859177b64e1a1e748a6e3ba62c2/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c", size = 146874 }, + { url = "https://files.pythonhosted.org/packages/75/d2/0ab54463d3410709c09266dfb416d032a08f97fd7d60e94b8c6ef54ae14b/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", size = 150871 }, + { url = "https://files.pythonhosted.org/packages/8d/c9/27e41d481557be53d51e60750b85aa40eaf52b841946b3cdeff363105737/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", size = 148546 }, + { url = "https://files.pythonhosted.org/packages/ee/44/4f62042ca8cdc0cabf87c0fc00ae27cd8b53ab68be3605ba6d071f742ad3/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", size = 143048 }, + { url = "https://files.pythonhosted.org/packages/01/f8/38842422988b795220eb8038745d27a675ce066e2ada79516c118f291f07/charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99", size = 94389 }, + { url = "https://files.pythonhosted.org/packages/0b/6e/b13bd47fa9023b3699e94abf565b5a2f0b0be6e9ddac9812182596ee62e4/charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27", size = 101752 }, + { url = "https://files.pythonhosted.org/packages/d3/0b/4b7a70987abf9b8196845806198975b6aab4ce016632f817ad758a5aa056/charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6", size = 194445 }, + { url = "https://files.pythonhosted.org/packages/50/89/354cc56cf4dd2449715bc9a0f54f3aef3dc700d2d62d1fa5bbea53b13426/charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf", size = 125275 }, + { url = "https://files.pythonhosted.org/packages/fa/44/b730e2a2580110ced837ac083d8ad222343c96bb6b66e9e4e706e4d0b6df/charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db", size = 119020 }, + { url = "https://files.pythonhosted.org/packages/9d/e4/9263b8240ed9472a2ae7ddc3e516e71ef46617fe40eaa51221ccd4ad9a27/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1", size = 139128 }, + { url = "https://files.pythonhosted.org/packages/6b/e3/9f73e779315a54334240353eaea75854a9a690f3f580e4bd85d977cb2204/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03", size = 149277 }, + { url = "https://files.pythonhosted.org/packages/1a/cf/f1f50c2f295312edb8a548d3fa56a5c923b146cd3f24114d5adb7e7be558/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284", size = 142174 }, + { url = "https://files.pythonhosted.org/packages/16/92/92a76dc2ff3a12e69ba94e7e05168d37d0345fa08c87e1fe24d0c2a42223/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15", size = 143838 }, + { url = "https://files.pythonhosted.org/packages/a4/01/2117ff2b1dfc61695daf2babe4a874bca328489afa85952440b59819e9d7/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8", size = 146149 }, + { url = "https://files.pythonhosted.org/packages/f6/9b/93a332b8d25b347f6839ca0a61b7f0287b0930216994e8bf67a75d050255/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2", size = 140043 }, + { url = "https://files.pythonhosted.org/packages/ab/f6/7ac4a01adcdecbc7a7587767c776d53d369b8b971382b91211489535acf0/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719", size = 148229 }, + { url = "https://files.pythonhosted.org/packages/9d/be/5708ad18161dee7dc6a0f7e6cf3a88ea6279c3e8484844c0590e50e803ef/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631", size = 151556 }, + { url = "https://files.pythonhosted.org/packages/5a/bb/3d8bc22bacb9eb89785e83e6723f9888265f3a0de3b9ce724d66bd49884e/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b", size = 149772 }, + { url = "https://files.pythonhosted.org/packages/f7/fa/d3fc622de05a86f30beea5fc4e9ac46aead4731e73fd9055496732bcc0a4/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565", size = 144800 }, + { url = "https://files.pythonhosted.org/packages/9a/65/bdb9bc496d7d190d725e96816e20e2ae3a6fa42a5cac99c3c3d6ff884118/charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7", size = 94836 }, + { url = "https://files.pythonhosted.org/packages/3e/67/7b72b69d25b89c0b3cea583ee372c43aa24df15f0e0f8d3982c57804984b/charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9", size = 102187 }, + { url = "https://files.pythonhosted.org/packages/bf/9b/08c0432272d77b04803958a4598a51e2a4b51c06640af8b8f0f908c18bf2/charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", size = 49446 }, +] + [[package]] name = "cobamp" version = "0.2.2" -source = { git = "https://github.com/JoshLoecker/cobamp?rev=update_packages#bccb9141e0cb35081cdaa4a98b25bcdaf2aa442a" } +source = { git = "https://github.com/JoshLoecker/cobamp?rev=master#17bb8d8de6f7bdbdf5b2ff5b25da2b365a68f568" } dependencies = [ { name = "boolean-py" }, { name = "indexed" }, @@ -166,6 +375,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, ] +[[package]] +name = "comm" +version = "0.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e9/a8/fb783cb0abe2b5fded9f55e5703015cdf1c9c85b3669087c538dd15a6a86/comm-0.2.2.tar.gz", hash = "sha256:3fd7a84065306e07bea1773df6eb8282de51ba82f77c72f9c85716ab11fe980e", size = 6210 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e6/75/49e5bfe642f71f272236b5b2d2691cf915a7283cc0ceda56357b61daa538/comm-0.2.2-py3-none-any.whl", hash = "sha256:e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3", size = 7180 }, +] + [[package]] name = "commitlint" version = "1.3.0" @@ -177,7 +398,7 @@ wheels = [ [[package]] name = "como" -version = "1.10.0" +version = "1.11.1" source = { editable = "." } dependencies = [ { name = "aiofiles" }, @@ -185,7 +406,6 @@ dependencies = [ { name = "cobamp" }, { name = "cobra" }, { name = "fast-bioservices" }, - { name = "gurobipy" }, { name = "kaleido" }, { name = "loguru" }, { name = "openpyxl" }, @@ -199,7 +419,7 @@ dependencies = [ { name = "troppo" }, ] -[package.dev-dependencies] +[package.optional-dependencies] dev = [ { name = "commitlint" }, { name = "hypothesis" }, @@ -208,35 +428,40 @@ dev = [ { name = "pytest-cov" }, { name = "ruff" }, ] +gurobi = [ + { name = "gurobipy" }, +] +interactive = [ + { name = "ipython" }, + { name = "jupyter" }, +] [package.metadata] requires-dist = [ { name = "aiofiles", specifier = ">=24.1.0" }, { name = "aioftp", specifier = ">=0.23.1" }, - { name = "cobamp", git = "https://github.com/JoshLoecker/cobamp?rev=update_packages" }, + { name = "cobamp", git = "https://github.com/JoshLoecker/cobamp?rev=master" }, { name = "cobra", specifier = ">=0.28.0" }, + { name = "commitlint", marker = "extra == 'dev'", specifier = ">=1.3.0" }, { name = "fast-bioservices", specifier = ">=0.3.9" }, - { name = "gurobipy", specifier = ">=11.0" }, + { name = "gurobipy", marker = "extra == 'gurobi'", specifier = ">=10.0.0" }, + { name = "hypothesis", marker = "extra == 'dev'", specifier = ">=6.122.1" }, + { name = "ipython", marker = "extra == 'interactive'" }, + { name = "jupyter", marker = "extra == 'interactive'" }, { name = "kaleido", specifier = "==0.2.1" }, { name = "loguru", specifier = ">=0.7.2" }, { name = "openpyxl", specifier = ">=3.1.5" }, { name = "pandas", specifier = ">=1.3.5" }, { name = "plotly", specifier = ">=5.24.1" }, + { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.3.3" }, + { name = "pytest-asyncio", marker = "extra == 'dev'", specifier = ">=0.24.0" }, + { name = "pytest-cov", marker = "extra == 'dev'", specifier = ">=6.0.0" }, + { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.8.0" }, { name = "scanpy", specifier = ">=1.9.8" }, { name = "scikit-learn", specifier = ">=1.5.2" }, { name = "scipy", specifier = ">=1.7.3" }, { name = "setuptools", specifier = "<60.0" }, - { name = "troppo", git = "https://github.com/JoshLoecker/troppo?rev=update_dependencies" }, -] - -[package.metadata.requires-dev] -dev = [ - { name = "commitlint", specifier = ">=1.3.0" }, - { name = "hypothesis", specifier = ">=6.122.1" }, - { name = "pytest", specifier = ">=8.3.3" }, - { name = "pytest-asyncio", specifier = ">=0.24.0" }, - { name = "pytest-cov", specifier = ">=6.0.0" }, - { name = "ruff", specifier = ">=0.8.0" }, + { name = "troppo", git = "https://github.com/JoshLoecker/troppo?rev=master" }, ] [[package]] @@ -334,6 +559,45 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321 }, ] +[[package]] +name = "debugpy" +version = "1.8.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/88/92/15b454c516c4c53cc8c03967e4be12b65a1ea36db3bb4513a7453f75c8d8/debugpy-1.8.9.zip", hash = "sha256:1339e14c7d980407248f09824d1b25ff5c5616651689f1e0f0e51bdead3ea13e", size = 4921695 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/2e/92fda96b1b773e454daae3e2962726dd9f7aedb1f26d7f2ca353d91a930b/debugpy-1.8.9-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:cfe1e6c6ad7178265f74981edf1154ffce97b69005212fbc90ca22ddfe3d017e", size = 2080529 }, + { url = "https://files.pythonhosted.org/packages/87/c0/d13cdbae394c7ae65ef93d7ccde2ff364445248e367bda93fc0650c08849/debugpy-1.8.9-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ada7fb65102a4d2c9ab62e8908e9e9f12aed9d76ef44880367bc9308ebe49a0f", size = 3565151 }, + { url = "https://files.pythonhosted.org/packages/23/40/237c0a7a68cb982dcced4a0199b7c464630f75b9280d6bebde32490135d1/debugpy-1.8.9-cp310-cp310-win32.whl", hash = "sha256:c36856343cbaa448171cba62a721531e10e7ffb0abff838004701454149bc037", size = 5117068 }, + { url = "https://files.pythonhosted.org/packages/00/89/e0be9f01ee461e3369dde418492244acb1b67adaf04cb5ea98f1380ab101/debugpy-1.8.9-cp310-cp310-win_amd64.whl", hash = "sha256:17c5e0297678442511cf00a745c9709e928ea4ca263d764e90d233208889a19e", size = 5149364 }, + { url = "https://files.pythonhosted.org/packages/f7/bf/c41b688ad490d644b3bcca505a87ea58ec0442234def9a641ba62dce9c11/debugpy-1.8.9-cp311-cp311-macosx_14_0_universal2.whl", hash = "sha256:b74a49753e21e33e7cf030883a92fa607bddc4ede1aa4145172debc637780040", size = 2179080 }, + { url = "https://files.pythonhosted.org/packages/f4/dd/e9de11423db7bde62469fbd932243c64f66d6d87924976f49ec336415522/debugpy-1.8.9-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62d22dacdb0e296966d7d74a7141aaab4bec123fa43d1a35ddcb39bf9fd29d70", size = 3137893 }, + { url = "https://files.pythonhosted.org/packages/2c/bf/e1f2c81220591728f35585b4abd67e71e9b39b3cb983f428b23d4ca6c22e/debugpy-1.8.9-cp311-cp311-win32.whl", hash = "sha256:8138efff315cd09b8dcd14226a21afda4ca582284bf4215126d87342bba1cc66", size = 5042644 }, + { url = "https://files.pythonhosted.org/packages/96/20/a407252954fd2812771e4ea3ab523f73889fd5027e305dec5ee4f0af149a/debugpy-1.8.9-cp311-cp311-win_amd64.whl", hash = "sha256:ff54ef77ad9f5c425398efb150239f6fe8e20c53ae2f68367eba7ece1e96226d", size = 5066943 }, + { url = "https://files.pythonhosted.org/packages/da/ab/1420baf8404d2b499349a44de5037133e06d489009032ce016fedb66eea1/debugpy-1.8.9-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:957363d9a7a6612a37458d9a15e72d03a635047f946e5fceee74b50d52a9c8e2", size = 2504180 }, + { url = "https://files.pythonhosted.org/packages/58/ec/e0f88c6764314bda7887274e0b980812709b3d6363dcae124a49a9ceaa3c/debugpy-1.8.9-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e565fc54b680292b418bb809f1386f17081d1346dca9a871bf69a8ac4071afe", size = 4224563 }, + { url = "https://files.pythonhosted.org/packages/dd/49/d9ea004ee2e4531d2b528841689ee2ba01c6a4b58840efd15e57dd866a86/debugpy-1.8.9-cp312-cp312-win32.whl", hash = "sha256:3e59842d6c4569c65ceb3751075ff8d7e6a6ada209ceca6308c9bde932bcef11", size = 5163641 }, + { url = "https://files.pythonhosted.org/packages/b1/63/c8b0718024c1187a446316037680e1564bf063c6665c815f17b42c244aba/debugpy-1.8.9-cp312-cp312-win_amd64.whl", hash = "sha256:66eeae42f3137eb428ea3a86d4a55f28da9bd5a4a3d369ba95ecc3a92c1bba53", size = 5203862 }, + { url = "https://files.pythonhosted.org/packages/2d/23/3f5804202da11c950dc0caae4a62d0c9aadabdb2daeb5f7aa09838647b5d/debugpy-1.8.9-py2.py3-none-any.whl", hash = "sha256:cc37a6c9987ad743d9c3a14fa1b1a14b7e4e6041f9dd0c8abf8895fe7a97b899", size = 5166094 }, +] + +[[package]] +name = "decorator" +version = "5.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/66/0c/8d907af351aa16b42caae42f9d6aa37b900c67308052d10fdce809f8d952/decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330", size = 35016 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d5/50/83c593b07763e1161326b3b8c6686f0f4b0f24d5526546bee538c89837d6/decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186", size = 9073 }, +] + +[[package]] +name = "defusedxml" +version = "0.7.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/d5/c66da9b79e5bdb124974bfe172b4daf3c984ebd9c2a06e2b8a4dc7331c72/defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", size = 75520 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61", size = 25604 }, +] + [[package]] name = "depinfo" version = "2.2.0" @@ -379,6 +643,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 }, ] +[[package]] +name = "executing" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/e3/7d45f492c2c4a0e8e0fad57d081a7c8a0286cdd86372b070cca1ec0caa1e/executing-2.1.0.tar.gz", hash = "sha256:8ea27ddd260da8150fa5a708269c4a10e76161e2496ec3e587da9e3c0fe4b9ab", size = 977485 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b5/fd/afcd0496feca3276f509df3dbd5dae726fcc756f1a08d9e25abe1733f962/executing-2.1.0-py2.py3-none-any.whl", hash = "sha256:8d63781349375b5ebccc3142f4b30350c0cd9c79f921cde38be2be4637e98eaf", size = 25805 }, +] + [[package]] name = "fast-bioservices" version = "0.3.9" @@ -396,6 +669,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/48/6c/6033e67a7d734ba90ff186e5404f78b0e3b59ae46e78bec11764ae50c508/fast_bioservices-0.3.9-py3-none-any.whl", hash = "sha256:f041a30300d4de5c7d2d5e0405b8505e7a7f79248e986ecf45ddb3473d7c4d8f", size = 22687 }, ] +[[package]] +name = "fastjsonschema" +version = "2.21.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8b/50/4b769ce1ac4071a1ef6d86b1a3fb56cdc3a37615e8c5519e1af96cdac366/fastjsonschema-2.21.1.tar.gz", hash = "sha256:794d4f0a58f848961ba16af7b9c85a3e88cd360df008c59aac6fc5ae9323b5d4", size = 373939 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/90/2b/0817a2b257fe88725c25589d89aec060581aabf668707a8d03b2e9e0cb2a/fastjsonschema-2.21.1-py3-none-any.whl", hash = "sha256:c9e5b7e908310918cf494a434eeb31384dd84a98b57a30bcb1f535015b554667", size = 23924 }, +] + [[package]] name = "fonttools" version = "4.54.1" @@ -429,6 +711,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/57/5e/de2e6e51cb6894f2f2bc2641f6c845561361b622e96df3cca04df77222c9/fonttools-4.54.1-py3-none-any.whl", hash = "sha256:37cddd62d83dc4f72f7c3f3c2bcf2697e89a30efb152079896544a93907733bd", size = 1096920 }, ] +[[package]] +name = "fqdn" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/3e/a80a8c077fd798951169626cde3e239adeba7dab75deb3555716415bd9b0/fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f", size = 6015 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014", size = 9121 }, +] + [[package]] name = "future" version = "1.0.0" @@ -584,6 +875,104 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, ] +[[package]] +name = "ipykernel" +version = "6.29.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "appnope", marker = "platform_system == 'Darwin'" }, + { name = "comm" }, + { name = "debugpy" }, + { name = "ipython" }, + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "matplotlib-inline" }, + { name = "nest-asyncio" }, + { name = "packaging" }, + { name = "psutil" }, + { name = "pyzmq" }, + { name = "tornado" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e9/5c/67594cb0c7055dc50814b21731c22a601101ea3b1b50a9a1b090e11f5d0f/ipykernel-6.29.5.tar.gz", hash = "sha256:f093a22c4a40f8828f8e330a9c297cb93dcab13bd9678ded6de8e5cf81c56215", size = 163367 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/5c/368ae6c01c7628438358e6d337c19b05425727fbb221d2a3c4303c372f42/ipykernel-6.29.5-py3-none-any.whl", hash = "sha256:afdb66ba5aa354b09b91379bac28ae4afebbb30e8b39510c9690afb7a10421b5", size = 117173 }, +] + +[[package]] +name = "ipython" +version = "8.30.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "decorator" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "jedi" }, + { name = "matplotlib-inline" }, + { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, + { name = "prompt-toolkit" }, + { name = "pygments" }, + { name = "stack-data" }, + { name = "traitlets" }, + { name = "typing-extensions", marker = "python_full_version < '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d8/8b/710af065ab8ed05649afa5bd1e07401637c9ec9fb7cfda9eac7e91e9fbd4/ipython-8.30.0.tar.gz", hash = "sha256:cb0a405a306d2995a5cbb9901894d240784a9f341394c6ba3f4fe8c6eb89ff6e", size = 5592205 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1d/f3/1332ba2f682b07b304ad34cad2f003adcfeb349486103f4b632335074a7c/ipython-8.30.0-py3-none-any.whl", hash = "sha256:85ec56a7e20f6c38fce7727dcca699ae4ffc85985aa7b23635a8008f918ae321", size = 820765 }, +] + +[[package]] +name = "ipywidgets" +version = "8.1.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "comm" }, + { name = "ipython" }, + { name = "jupyterlab-widgets" }, + { name = "traitlets" }, + { name = "widgetsnbextension" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c7/4c/dab2a281b07596a5fc220d49827fe6c794c66f1493d7a74f1df0640f2cc5/ipywidgets-8.1.5.tar.gz", hash = "sha256:870e43b1a35656a80c18c9503bbf2d16802db1cb487eec6fab27d683381dde17", size = 116723 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/2d/9c0b76f2f9cc0ebede1b9371b6f317243028ed60b90705863d493bae622e/ipywidgets-8.1.5-py3-none-any.whl", hash = "sha256:3290f526f87ae6e77655555baba4f36681c555b8bdbbff430b70e52c34c86245", size = 139767 }, +] + +[[package]] +name = "isoduration" +version = "20.11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "arrow" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7c/1a/3c8edc664e06e6bd06cce40c6b22da5f1429aa4224d0c590f3be21c91ead/isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9", size = 11649 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042", size = 11321 }, +] + +[[package]] +name = "jedi" +version = "0.19.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "parso" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/72/3a/79a912fbd4d8dd6fbb02bf69afd3bb72cf0c729bb3063c6f4498603db17a/jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0", size = 1231287 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278 }, +] + +[[package]] +name = "jinja2" +version = "3.1.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ed/55/39036716d19cab0747a5020fc7e907f362fbf48c984b14e62127f7e68e5d/jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", size = 240245 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/31/80/3a54838c3fb461f6fec263ebf3a3a41771bd05190238de3486aae8540c36/jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d", size = 133271 }, +] + [[package]] name = "joblib" version = "1.4.2" @@ -593,6 +982,263 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/91/29/df4b9b42f2be0b623cbd5e2140cafcaa2bef0759a00b7b70104dcfe2fb51/joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6", size = 301817 }, ] +[[package]] +name = "json5" +version = "0.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/85/3d/bbe62f3d0c05a689c711cff57b2e3ac3d3e526380adb7c781989f075115c/json5-0.10.0.tar.gz", hash = "sha256:e66941c8f0a02026943c52c2eb34ebeb2a6f819a0be05920a6f5243cd30fd559", size = 48202 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/aa/42/797895b952b682c3dafe23b1834507ee7f02f4d6299b65aaa61425763278/json5-0.10.0-py3-none-any.whl", hash = "sha256:19b23410220a7271e8377f81ba8aacba2fdd56947fbb137ee5977cbe1f5e8dfa", size = 34049 }, +] + +[[package]] +name = "jsonpointer" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/0a/eebeb1fa92507ea94016a2a790b93c2ae41a7e18778f85471dc54475ed25/jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef", size = 9114 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942", size = 7595 }, +] + +[[package]] +name = "jsonschema" +version = "4.23.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "jsonschema-specifications" }, + { name = "referencing" }, + { name = "rpds-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/38/2e/03362ee4034a4c917f697890ccd4aec0800ccf9ded7f511971c75451deec/jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4", size = 325778 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/4a/4f9dbeb84e8850557c02365a0eee0649abe5eb1d84af92a25731c6c0f922/jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566", size = 88462 }, +] + +[package.optional-dependencies] +format-nongpl = [ + { name = "fqdn" }, + { name = "idna" }, + { name = "isoduration" }, + { name = "jsonpointer" }, + { name = "rfc3339-validator" }, + { name = "rfc3986-validator" }, + { name = "uri-template" }, + { name = "webcolors" }, +] + +[[package]] +name = "jsonschema-specifications" +version = "2024.10.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "referencing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/10/db/58f950c996c793472e336ff3655b13fbcf1e3b359dcf52dcf3ed3b52c352/jsonschema_specifications-2024.10.1.tar.gz", hash = "sha256:0f38b83639958ce1152d02a7f062902c41c8fd20d558b0c34344292d417ae272", size = 15561 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/0f/8910b19ac0670a0f80ce1008e5e751c4a57e14d2c4c13a482aa6079fa9d6/jsonschema_specifications-2024.10.1-py3-none-any.whl", hash = "sha256:a09a0680616357d9a0ecf05c12ad234479f549239d0f5b55f3deea67475da9bf", size = 18459 }, +] + +[[package]] +name = "jupyter" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ipykernel" }, + { name = "ipywidgets" }, + { name = "jupyter-console" }, + { name = "jupyterlab" }, + { name = "nbconvert" }, + { name = "notebook" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/58/f3/af28ea964ab8bc1e472dba2e82627d36d470c51f5cd38c37502eeffaa25e/jupyter-1.1.1.tar.gz", hash = "sha256:d55467bceabdea49d7e3624af7e33d59c37fff53ed3a350e1ac957bed731de7a", size = 5714959 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/64/285f20a31679bf547b75602702f7800e74dbabae36ef324f716c02804753/jupyter-1.1.1-py2.py3-none-any.whl", hash = "sha256:7a59533c22af65439b24bbe60373a4e95af8f16ac65a6c00820ad378e3f7cc83", size = 2657 }, +] + +[[package]] +name = "jupyter-client" +version = "8.6.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-core" }, + { name = "python-dateutil" }, + { name = "pyzmq" }, + { name = "tornado" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/71/22/bf9f12fdaeae18019a468b68952a60fe6dbab5d67cd2a103cac7659b41ca/jupyter_client-8.6.3.tar.gz", hash = "sha256:35b3a0947c4a6e9d589eb97d7d4cd5e90f910ee73101611f01283732bd6d9419", size = 342019 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/11/85/b0394e0b6fcccd2c1eeefc230978a6f8cb0c5df1e4cd3e7625735a0d7d1e/jupyter_client-8.6.3-py3-none-any.whl", hash = "sha256:e8a19cc986cc45905ac3362915f410f3af85424b4c0905e94fa5f2cb08e8f23f", size = 106105 }, +] + +[[package]] +name = "jupyter-console" +version = "6.6.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ipykernel" }, + { name = "ipython" }, + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "prompt-toolkit" }, + { name = "pygments" }, + { name = "pyzmq" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bd/2d/e2fd31e2fc41c14e2bcb6c976ab732597e907523f6b2420305f9fc7fdbdb/jupyter_console-6.6.3.tar.gz", hash = "sha256:566a4bf31c87adbfadf22cdf846e3069b59a71ed5da71d6ba4d8aaad14a53539", size = 34363 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/77/71d78d58f15c22db16328a476426f7ac4a60d3a5a7ba3b9627ee2f7903d4/jupyter_console-6.6.3-py3-none-any.whl", hash = "sha256:309d33409fcc92ffdad25f0bcdf9a4a9daa61b6f341177570fdac03de5352485", size = 24510 }, +] + +[[package]] +name = "jupyter-core" +version = "5.7.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "platformdirs" }, + { name = "pywin32", marker = "platform_python_implementation != 'PyPy' and sys_platform == 'win32'" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/00/11/b56381fa6c3f4cc5d2cf54a7dbf98ad9aa0b339ef7a601d6053538b079a7/jupyter_core-5.7.2.tar.gz", hash = "sha256:aa5f8d32bbf6b431ac830496da7392035d6f61b4f54872f15c4bd2a9c3f536d9", size = 87629 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c9/fb/108ecd1fe961941959ad0ee4e12ee7b8b1477247f30b1fdfd83ceaf017f0/jupyter_core-5.7.2-py3-none-any.whl", hash = "sha256:4f7315d2f6b4bcf2e3e7cb6e46772eba760ae459cd1f59d29eb57b0a01bd7409", size = 28965 }, +] + +[[package]] +name = "jupyter-events" +version = "0.10.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jsonschema", extra = ["format-nongpl"] }, + { name = "python-json-logger" }, + { name = "pyyaml" }, + { name = "referencing" }, + { name = "rfc3339-validator" }, + { name = "rfc3986-validator" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8d/53/7537a1aa558229bb0b1b178d814c9d68a9c697d3aecb808a1cb2646acf1f/jupyter_events-0.10.0.tar.gz", hash = "sha256:670b8229d3cc882ec782144ed22e0d29e1c2d639263f92ca8383e66682845e22", size = 61516 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a5/94/059180ea70a9a326e1815176b2370da56376da347a796f8c4f0b830208ef/jupyter_events-0.10.0-py3-none-any.whl", hash = "sha256:4b72130875e59d57716d327ea70d3ebc3af1944d3717e5a498b8a06c6c159960", size = 18777 }, +] + +[[package]] +name = "jupyter-lsp" +version = "2.2.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-server" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/85/b4/3200b0b09c12bc3b72d943d923323c398eff382d1dcc7c0dbc8b74630e40/jupyter-lsp-2.2.5.tar.gz", hash = "sha256:793147a05ad446f809fd53ef1cd19a9f5256fd0a2d6b7ce943a982cb4f545001", size = 48741 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/e0/7bd7cff65594fd9936e2f9385701e44574fc7d721331ff676ce440b14100/jupyter_lsp-2.2.5-py3-none-any.whl", hash = "sha256:45fbddbd505f3fbfb0b6cb2f1bc5e15e83ab7c79cd6e89416b248cb3c00c11da", size = 69146 }, +] + +[[package]] +name = "jupyter-server" +version = "2.14.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "argon2-cffi" }, + { name = "jinja2" }, + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "jupyter-events" }, + { name = "jupyter-server-terminals" }, + { name = "nbconvert" }, + { name = "nbformat" }, + { name = "overrides" }, + { name = "packaging" }, + { name = "prometheus-client" }, + { name = "pywinpty", marker = "os_name == 'nt'" }, + { name = "pyzmq" }, + { name = "send2trash" }, + { name = "terminado" }, + { name = "tornado" }, + { name = "traitlets" }, + { name = "websocket-client" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0c/34/88b47749c7fa9358e10eac356c4b97d94a91a67d5c935a73f69bc4a31118/jupyter_server-2.14.2.tar.gz", hash = "sha256:66095021aa9638ced276c248b1d81862e4c50f292d575920bbe960de1c56b12b", size = 719933 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/57/e1/085edea6187a127ca8ea053eb01f4e1792d778b4d192c74d32eb6730fed6/jupyter_server-2.14.2-py3-none-any.whl", hash = "sha256:47ff506127c2f7851a17bf4713434208fc490955d0e8632e95014a9a9afbeefd", size = 383556 }, +] + +[[package]] +name = "jupyter-server-terminals" +version = "0.5.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pywinpty", marker = "os_name == 'nt'" }, + { name = "terminado" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fc/d5/562469734f476159e99a55426d697cbf8e7eb5efe89fb0e0b4f83a3d3459/jupyter_server_terminals-0.5.3.tar.gz", hash = "sha256:5ae0295167220e9ace0edcfdb212afd2b01ee8d179fe6f23c899590e9b8a5269", size = 31430 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/2d/2b32cdbe8d2a602f697a649798554e4f072115438e92249624e532e8aca6/jupyter_server_terminals-0.5.3-py3-none-any.whl", hash = "sha256:41ee0d7dc0ebf2809c668e0fc726dfaf258fcd3e769568996ca731b6194ae9aa", size = 13656 }, +] + +[[package]] +name = "jupyterlab" +version = "4.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "async-lru" }, + { name = "httpx" }, + { name = "ipykernel" }, + { name = "jinja2" }, + { name = "jupyter-core" }, + { name = "jupyter-lsp" }, + { name = "jupyter-server" }, + { name = "jupyterlab-server" }, + { name = "notebook-shim" }, + { name = "packaging" }, + { name = "setuptools" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "tornado" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c3/ca/b80ea37f800b7d0b96088dec04d59b4575eb33e59ca1ca19d23885fb6fe6/jupyterlab-4.3.3.tar.gz", hash = "sha256:76fa39e548fdac94dc1204af5956c556f54c785f70ee26aa47ea08eda4d5bbcd", size = 21797278 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/ce/6731e54aacbe91daa439ae895763fe9d91952ce96cd0e3f94d8d13229717/jupyterlab-4.3.3-py3-none-any.whl", hash = "sha256:32a8fd30677e734ffcc3916a4758b9dab21b02015b668c60eb36f84357b7d4b1", size = 11665394 }, +] + +[[package]] +name = "jupyterlab-pygments" +version = "0.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/90/51/9187be60d989df97f5f0aba133fa54e7300f17616e065d1ada7d7646b6d6/jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d", size = 512900 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780", size = 15884 }, +] + +[[package]] +name = "jupyterlab-server" +version = "2.27.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "babel" }, + { name = "jinja2" }, + { name = "json5" }, + { name = "jsonschema" }, + { name = "jupyter-server" }, + { name = "packaging" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0a/c9/a883ce65eb27905ce77ace410d83587c82ea64dc85a48d1f7ed52bcfa68d/jupyterlab_server-2.27.3.tar.gz", hash = "sha256:eb36caca59e74471988f0ae25c77945610b887f777255aa21f8065def9e51ed4", size = 76173 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/09/2032e7d15c544a0e3cd831c51d77a8ca57f7555b2e1b2922142eddb02a84/jupyterlab_server-2.27.3-py3-none-any.whl", hash = "sha256:e697488f66c3db49df675158a77b3b017520d772c6e1548c7d9bcc5df7944ee4", size = 59700 }, +] + +[[package]] +name = "jupyterlab-widgets" +version = "3.0.13" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/59/73/fa26bbb747a9ea4fca6b01453aa22990d52ab62dd61384f1ac0dc9d4e7ba/jupyterlab_widgets-3.0.13.tar.gz", hash = "sha256:a2966d385328c1942b683a8cd96b89b8dd82c8b8f81dda902bb2bc06d46f5bed", size = 203556 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a9/93/858e87edc634d628e5d752ba944c2833133a28fa87bb093e6832ced36a3e/jupyterlab_widgets-3.0.13-py3-none-any.whl", hash = "sha256:e3cda2c233ce144192f1e29914ad522b2f4c40e77214b0cc97377ca3d323db54", size = 214392 }, +] + [[package]] name = "kaleido" version = "0.2.1" @@ -725,6 +1371,44 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528 }, ] +[[package]] +name = "markupsafe" +version = "3.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/90/d08277ce111dd22f77149fd1a5d4653eeb3b3eaacbdfcbae5afb2600eebd/MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", size = 14357 }, + { url = "https://files.pythonhosted.org/packages/04/e1/6e2194baeae0bca1fae6629dc0cbbb968d4d941469cbab11a3872edff374/MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", size = 12393 }, + { url = "https://files.pythonhosted.org/packages/1d/69/35fa85a8ece0a437493dc61ce0bb6d459dcba482c34197e3efc829aa357f/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", size = 21732 }, + { url = "https://files.pythonhosted.org/packages/22/35/137da042dfb4720b638d2937c38a9c2df83fe32d20e8c8f3185dbfef05f7/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", size = 20866 }, + { url = "https://files.pythonhosted.org/packages/29/28/6d029a903727a1b62edb51863232152fd335d602def598dade38996887f0/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", size = 20964 }, + { url = "https://files.pythonhosted.org/packages/cc/cd/07438f95f83e8bc028279909d9c9bd39e24149b0d60053a97b2bc4f8aa51/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", size = 21977 }, + { url = "https://files.pythonhosted.org/packages/29/01/84b57395b4cc062f9c4c55ce0df7d3108ca32397299d9df00fedd9117d3d/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", size = 21366 }, + { url = "https://files.pythonhosted.org/packages/bd/6e/61ebf08d8940553afff20d1fb1ba7294b6f8d279df9fd0c0db911b4bbcfd/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", size = 21091 }, + { url = "https://files.pythonhosted.org/packages/11/23/ffbf53694e8c94ebd1e7e491de185124277964344733c45481f32ede2499/MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50", size = 15065 }, + { url = "https://files.pythonhosted.org/packages/44/06/e7175d06dd6e9172d4a69a72592cb3f7a996a9c396eee29082826449bbc3/MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", size = 15514 }, + { url = "https://files.pythonhosted.org/packages/6b/28/bbf83e3f76936960b850435576dd5e67034e200469571be53f69174a2dfd/MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", size = 14353 }, + { url = "https://files.pythonhosted.org/packages/6c/30/316d194b093cde57d448a4c3209f22e3046c5bb2fb0820b118292b334be7/MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", size = 12392 }, + { url = "https://files.pythonhosted.org/packages/f2/96/9cdafba8445d3a53cae530aaf83c38ec64c4d5427d975c974084af5bc5d2/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", size = 23984 }, + { url = "https://files.pythonhosted.org/packages/f1/a4/aefb044a2cd8d7334c8a47d3fb2c9f328ac48cb349468cc31c20b539305f/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", size = 23120 }, + { url = "https://files.pythonhosted.org/packages/8d/21/5e4851379f88f3fad1de30361db501300d4f07bcad047d3cb0449fc51f8c/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", size = 23032 }, + { url = "https://files.pythonhosted.org/packages/00/7b/e92c64e079b2d0d7ddf69899c98842f3f9a60a1ae72657c89ce2655c999d/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", size = 24057 }, + { url = "https://files.pythonhosted.org/packages/f9/ac/46f960ca323037caa0a10662ef97d0a4728e890334fc156b9f9e52bcc4ca/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", size = 23359 }, + { url = "https://files.pythonhosted.org/packages/69/84/83439e16197337b8b14b6a5b9c2105fff81d42c2a7c5b58ac7b62ee2c3b1/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", size = 23306 }, + { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094 }, + { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521 }, + { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274 }, + { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348 }, + { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149 }, + { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118 }, + { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993 }, + { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178 }, + { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319 }, + { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352 }, + { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097 }, + { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601 }, +] + [[package]] name = "matplotlib" version = "3.8.4" @@ -763,6 +1447,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7d/ca/e7bd1876a341ed8c456095962a582696cac1691cb6e55bd5ead15a755c5d/matplotlib-3.8.4-cp312-cp312-win_amd64.whl", hash = "sha256:7a6769f58ce51791b4cb8b4d7642489df347697cd3e23d88266aaaee93b41d9a", size = 7659712 }, ] +[[package]] +name = "matplotlib-inline" +version = "0.1.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/99/5b/a36a337438a14116b16480db471ad061c36c3694df7c2084a0da7ba538b7/matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90", size = 8159 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8f/8e/9ad090d3553c280a8060fbf6e24dc1c0c29704ee7d1c372f0c174aa59285/matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca", size = 9899 }, +] + [[package]] name = "mdurl" version = "0.1.2" @@ -772,6 +1468,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 }, ] +[[package]] +name = "mistune" +version = "3.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ef/c8/f0173fe3bf85fd891aee2e7bcd8207dfe26c2c683d727c5a6cc3aec7b628/mistune-3.0.2.tar.gz", hash = "sha256:fc7f93ded930c92394ef2cb6f04a8aabab4117a91449e72dcc8dfa646a508be8", size = 90840 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f0/74/c95adcdf032956d9ef6c89a9b8a5152bf73915f8c633f3e3d88d06bd699c/mistune-3.0.2-py3-none-any.whl", hash = "sha256:71481854c30fdbc938963d3605b72501f5c10a9320ecd412c121c163a1c7d205", size = 47958 }, +] + [[package]] name = "mpmath" version = "1.3.0" @@ -809,6 +1514,71 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ef/82/7a9d0550484a62c6da82858ee9419f3dd1ccc9aa1c26a1e43da3ecd20b0d/natsort-8.4.0-py3-none-any.whl", hash = "sha256:4732914fb471f56b5cce04d7bae6f164a592c7712e1c85f9ef585e197299521c", size = 38268 }, ] +[[package]] +name = "nbclient" +version = "0.10.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "nbformat" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/db/25929926860ba8a3f6123d2d0a235e558e0e4be7b46e9db063a7dfefa0a2/nbclient-0.10.1.tar.gz", hash = "sha256:3e93e348ab27e712acd46fccd809139e356eb9a31aab641d1a7991a6eb4e6f68", size = 62273 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/26/1a/ed6d1299b1a00c1af4a033fdee565f533926d819e084caf0d2832f6f87c6/nbclient-0.10.1-py3-none-any.whl", hash = "sha256:949019b9240d66897e442888cfb618f69ef23dc71c01cb5fced8499c2cfc084d", size = 25344 }, +] + +[[package]] +name = "nbconvert" +version = "7.16.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, + { name = "bleach" }, + { name = "defusedxml" }, + { name = "jinja2" }, + { name = "jupyter-core" }, + { name = "jupyterlab-pygments" }, + { name = "markupsafe" }, + { name = "mistune" }, + { name = "nbclient" }, + { name = "nbformat" }, + { name = "packaging" }, + { name = "pandocfilters" }, + { name = "pygments" }, + { name = "tinycss2" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/af/e8/ba521a033b21132008e520c28ceb818f9f092da5f0261e94e509401b29f9/nbconvert-7.16.4.tar.gz", hash = "sha256:86ca91ba266b0a448dc96fa6c5b9d98affabde2867b363258703536807f9f7f4", size = 854422 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b8/bb/bb5b6a515d1584aa2fd89965b11db6632e4bdc69495a52374bcc36e56cfa/nbconvert-7.16.4-py3-none-any.whl", hash = "sha256:05873c620fe520b6322bf8a5ad562692343fe3452abda5765c7a34b7d1aa3eb3", size = 257388 }, +] + +[[package]] +name = "nbformat" +version = "5.10.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "fastjsonschema" }, + { name = "jsonschema" }, + { name = "jupyter-core" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6d/fd/91545e604bc3dad7dca9ed03284086039b294c6b3d75c0d2fa45f9e9caf3/nbformat-5.10.4.tar.gz", hash = "sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a", size = 142749 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl", hash = "sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b", size = 78454 }, +] + +[[package]] +name = "nest-asyncio" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/83/f8/51569ac65d696c8ecbee95938f89d4abf00f47d58d48f6fbabfe8f0baefe/nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe", size = 7418 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c", size = 5195 }, +] + [[package]] name = "networkx" version = "3.2.1" @@ -818,6 +1588,34 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d5/f0/8fbc882ca80cf077f1b246c0e3c3465f7f415439bdea6b899f6b19f61f70/networkx-3.2.1-py3-none-any.whl", hash = "sha256:f18c69adc97877c42332c170849c96cefa91881c99a7cb3e95b7c659ebdc1ec2", size = 1647772 }, ] +[[package]] +name = "notebook" +version = "7.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-server" }, + { name = "jupyterlab" }, + { name = "jupyterlab-server" }, + { name = "notebook-shim" }, + { name = "tornado" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2a/1f/6c90511ea21b4ed6444e61ec8bb4137cb8c34db0f3b82402094286babbdf/notebook-7.3.1.tar.gz", hash = "sha256:84381c2a82d867517fd25b86e986dae1fe113a70b98f03edff9b94e499fec8fa", size = 12777449 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/c4/764078234460706fdd2da68f1715ee42359cb24ee18b70db051cfac38455/notebook-7.3.1-py3-none-any.whl", hash = "sha256:212e1486b2230fe22279043f33c7db5cf9a01d29feb063a85cb139747b7c9483", size = 13162639 }, +] + +[[package]] +name = "notebook-shim" +version = "0.2.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-server" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/54/d2/92fa3243712b9a3e8bafaf60aac366da1cada3639ca767ff4b5b3654ec28/notebook_shim-0.2.4.tar.gz", hash = "sha256:b4b2cfa1b65d98307ca24361f5b30fe785b53c3fd07b7a47e89acb5e6ac638cb", size = 13167 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl", hash = "sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef", size = 13307 }, +] + [[package]] name = "numba" version = "0.53.1" @@ -948,6 +1746,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/12/3e/9d0b72cf5a8ff660e5787a0797906e04942081f3ad4a95f860488affff2b/optlang-1.5.2-py2.py3-none-any.whl", hash = "sha256:14464cff638b58670c1a7f5896f19dd7b595a12c1d30a27c59074700833c1677", size = 147733 }, ] +[[package]] +name = "overrides" +version = "7.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/36/86/b585f53236dec60aba864e050778b25045f857e17f6e5ea0ae95fe80edd2/overrides-7.7.0.tar.gz", hash = "sha256:55158fa3d93b98cc75299b1e67078ad9003ca27945c76162c1c0766d6f91820a", size = 22812 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/ab/fc8290c6a4c722e5514d80f62b2dc4c4df1a68a41d1364e625c35990fcf3/overrides-7.7.0-py3-none-any.whl", hash = "sha256:c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49", size = 17832 }, +] + [[package]] name = "packaging" version = "24.1" @@ -993,6 +1800,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/29/d4/1244ab8edf173a10fd601f7e13b9566c1b525c4f365d6bee918e68381889/pandas-2.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:59ef3764d0fe818125a5097d2ae867ca3fa64df032331b7e0917cf5d7bf66b13", size = 11504248 }, ] +[[package]] +name = "pandocfilters" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/70/6f/3dd4940bbe001c06a65f88e36bad298bc7a0de5036115639926b0c5c0458/pandocfilters-1.5.1.tar.gz", hash = "sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e", size = 8454 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl", hash = "sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc", size = 8663 }, +] + +[[package]] +name = "parso" +version = "0.8.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/66/94/68e2e17afaa9169cf6412ab0f28623903be73d1b32e208d9e8e541bb086d/parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d", size = 400609 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c6/ac/dac4a63f978e4dcb3c6d3a78c4d8e0192a113d288502a1216950c41b1027/parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18", size = 103650 }, +] + [[package]] name = "pathos" version = "0.3.3" @@ -1022,6 +1847,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/43/f3/1d311a09c34f14f5973bb0bb0dc3a6e007e1eda90b5492d082689936ca51/patsy-0.5.6-py2.py3-none-any.whl", hash = "sha256:19056886fd8fa71863fa32f0eb090267f21fb74be00f19f5c70b2e9d76c883c6", size = 233945 }, ] +[[package]] +name = "pexpect" +version = "4.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ptyprocess" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772 }, +] + [[package]] name = "pillow" version = "11.0.0" @@ -1070,6 +1907,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/3d/c32a51d848401bd94cabb8767a39621496491ee7cd5199856b77da9b18ad/pillow-11.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:224aaa38177597bb179f3ec87eeefcce8e4f85e608025e9cfac60de237ba6316", size = 2567508 }, ] +[[package]] +name = "platformdirs" +version = "4.3.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/fc/128cc9cb8f03208bdbf93d3aa862e16d376844a14f9a0ce5cf4507372de4/platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", size = 21302 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb", size = 18439 }, +] + [[package]] name = "plotly" version = "5.24.1" @@ -1110,6 +1956,69 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/02/b3/45a04dabc39d93ad4836d99625e7c5350257b48e9ae2c5b701f3d5da6960/ppft-1.7.6.9-py3-none-any.whl", hash = "sha256:dab36548db5ca3055067fbe6b1a17db5fee29f3c366c579a9a27cebb52ed96f0", size = 56792 }, ] +[[package]] +name = "prometheus-client" +version = "0.21.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/62/14/7d0f567991f3a9af8d1cd4f619040c93b68f09a02b6d0b6ab1b2d1ded5fe/prometheus_client-0.21.1.tar.gz", hash = "sha256:252505a722ac04b0456be05c05f75f45d760c2911ffc45f2a06bcaed9f3ae3fb", size = 78551 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ff/c2/ab7d37426c179ceb9aeb109a85cda8948bb269b7561a0be870cc656eefe4/prometheus_client-0.21.1-py3-none-any.whl", hash = "sha256:594b45c410d6f4f8888940fe80b5cc2521b305a1fafe1c58609ef715a001f301", size = 54682 }, +] + +[[package]] +name = "prompt-toolkit" +version = "3.0.48" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wcwidth" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2d/4f/feb5e137aff82f7c7f3248267b97451da3644f6cdc218edfe549fb354127/prompt_toolkit-3.0.48.tar.gz", hash = "sha256:d6623ab0477a80df74e646bdbc93621143f5caf104206aa29294d53de1a03d90", size = 424684 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a9/6a/fd08d94654f7e67c52ca30523a178b3f8ccc4237fce4be90d39c938a831a/prompt_toolkit-3.0.48-py3-none-any.whl", hash = "sha256:f49a827f90062e411f1ce1f854f2aedb3c23353244f8108b89283587397ac10e", size = 386595 }, +] + +[[package]] +name = "psutil" +version = "6.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/26/10/2a30b13c61e7cf937f4adf90710776b7918ed0a9c434e2c38224732af310/psutil-6.1.0.tar.gz", hash = "sha256:353815f59a7f64cdaca1c0307ee13558a0512f6db064e92fe833784f08539c7a", size = 508565 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/01/9e/8be43078a171381953cfee33c07c0d628594b5dbfc5157847b85022c2c1b/psutil-6.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6e2dcd475ce8b80522e51d923d10c7871e45f20918e027ab682f94f1c6351688", size = 247762 }, + { url = "https://files.pythonhosted.org/packages/1d/cb/313e80644ea407f04f6602a9e23096540d9dc1878755f3952ea8d3d104be/psutil-6.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0895b8414afafc526712c498bd9de2b063deaac4021a3b3c34566283464aff8e", size = 248777 }, + { url = "https://files.pythonhosted.org/packages/65/8e/bcbe2025c587b5d703369b6a75b65d41d1367553da6e3f788aff91eaf5bd/psutil-6.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dcbfce5d89f1d1f2546a2090f4fcf87c7f669d1d90aacb7d7582addece9fb38", size = 284259 }, + { url = "https://files.pythonhosted.org/packages/58/4d/8245e6f76a93c98aab285a43ea71ff1b171bcd90c9d238bf81f7021fb233/psutil-6.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:498c6979f9c6637ebc3a73b3f87f9eb1ec24e1ce53a7c5173b8508981614a90b", size = 287255 }, + { url = "https://files.pythonhosted.org/packages/27/c2/d034856ac47e3b3cdfa9720d0e113902e615f4190d5d1bdb8df4b2015fb2/psutil-6.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d905186d647b16755a800e7263d43df08b790d709d575105d419f8b6ef65423a", size = 288804 }, + { url = "https://files.pythonhosted.org/packages/ea/55/5389ed243c878725feffc0d6a3bc5ef6764312b6fc7c081faaa2cfa7ef37/psutil-6.1.0-cp37-abi3-win32.whl", hash = "sha256:1ad45a1f5d0b608253b11508f80940985d1d0c8f6111b5cb637533a0e6ddc13e", size = 250386 }, + { url = "https://files.pythonhosted.org/packages/11/91/87fa6f060e649b1e1a7b19a4f5869709fbf750b7c8c262ee776ec32f3028/psutil-6.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:a8fb3752b491d246034fa4d279ff076501588ce8cbcdbb62c32fd7a377d996be", size = 254228 }, +] + +[[package]] +name = "ptyprocess" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993 }, +] + +[[package]] +name = "pure-eval" +version = "0.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42", size = 19752 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842 }, +] + +[[package]] +name = "pycparser" +version = "2.22" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552 }, +] + [[package]] name = "pydantic" version = "2.9.2" @@ -1270,6 +2179,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 }, ] +[[package]] +name = "python-json-logger" +version = "3.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b6/df/8a6015e77e26250c7cd016ed9487c2e5360e315da149d9663dc71b826237/python_json_logger-3.2.0.tar.gz", hash = "sha256:2c11056458d3f56614480b24e9cb28f7aba69cbfbebddbb77c92f0ec0d4947ab", size = 16160 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c3/be/a84e771466c68a33eda7efb5a274e4045dfb6ae3dc846ac153b62e14e7bd/python_json_logger-3.2.0-py3-none-any.whl", hash = "sha256:d73522ddcfc6d0461394120feaddea9025dc64bf804d96357dd42fa878cc5fe8", size = 14794 }, +] + [[package]] name = "python-libsbml" version = "5.20.4" @@ -1315,6 +2233,169 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/11/c3/005fcca25ce078d2cc29fd559379817424e94885510568bc1bc53d7d5846/pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725", size = 508002 }, ] +[[package]] +name = "pywin32" +version = "308" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/72/a6/3e9f2c474895c1bb61b11fa9640be00067b5c5b363c501ee9c3fa53aec01/pywin32-308-cp310-cp310-win32.whl", hash = "sha256:796ff4426437896550d2981b9c2ac0ffd75238ad9ea2d3bfa67a1abd546d262e", size = 5927028 }, + { url = "https://files.pythonhosted.org/packages/d9/b4/84e2463422f869b4b718f79eb7530a4c1693e96b8a4e5e968de38be4d2ba/pywin32-308-cp310-cp310-win_amd64.whl", hash = "sha256:4fc888c59b3c0bef905ce7eb7e2106a07712015ea1c8234b703a088d46110e8e", size = 6558484 }, + { url = "https://files.pythonhosted.org/packages/9f/8f/fb84ab789713f7c6feacaa08dad3ec8105b88ade8d1c4f0f0dfcaaa017d6/pywin32-308-cp310-cp310-win_arm64.whl", hash = "sha256:a5ab5381813b40f264fa3495b98af850098f814a25a63589a8e9eb12560f450c", size = 7971454 }, + { url = "https://files.pythonhosted.org/packages/eb/e2/02652007469263fe1466e98439831d65d4ca80ea1a2df29abecedf7e47b7/pywin32-308-cp311-cp311-win32.whl", hash = "sha256:5d8c8015b24a7d6855b1550d8e660d8daa09983c80e5daf89a273e5c6fb5095a", size = 5928156 }, + { url = "https://files.pythonhosted.org/packages/48/ef/f4fb45e2196bc7ffe09cad0542d9aff66b0e33f6c0954b43e49c33cad7bd/pywin32-308-cp311-cp311-win_amd64.whl", hash = "sha256:575621b90f0dc2695fec346b2d6302faebd4f0f45c05ea29404cefe35d89442b", size = 6559559 }, + { url = "https://files.pythonhosted.org/packages/79/ef/68bb6aa865c5c9b11a35771329e95917b5559845bd75b65549407f9fc6b4/pywin32-308-cp311-cp311-win_arm64.whl", hash = "sha256:100a5442b7332070983c4cd03f2e906a5648a5104b8a7f50175f7906efd16bb6", size = 7972495 }, + { url = "https://files.pythonhosted.org/packages/00/7c/d00d6bdd96de4344e06c4afbf218bc86b54436a94c01c71a8701f613aa56/pywin32-308-cp312-cp312-win32.whl", hash = "sha256:587f3e19696f4bf96fde9d8a57cec74a57021ad5f204c9e627e15c33ff568897", size = 5939729 }, + { url = "https://files.pythonhosted.org/packages/21/27/0c8811fbc3ca188f93b5354e7c286eb91f80a53afa4e11007ef661afa746/pywin32-308-cp312-cp312-win_amd64.whl", hash = "sha256:00b3e11ef09ede56c6a43c71f2d31857cf7c54b0ab6e78ac659497abd2834f47", size = 6543015 }, + { url = "https://files.pythonhosted.org/packages/9d/0f/d40f8373608caed2255781a3ad9a51d03a594a1248cd632d6a298daca693/pywin32-308-cp312-cp312-win_arm64.whl", hash = "sha256:9b4de86c8d909aed15b7011182c8cab38c8850de36e6afb1f0db22b8959e3091", size = 7976033 }, +] + +[[package]] +name = "pywinpty" +version = "2.0.14" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/82/90f8750423cba4b9b6c842df227609fb60704482d7abf6dd47e2babc055a/pywinpty-2.0.14.tar.gz", hash = "sha256:18bd9529e4a5daf2d9719aa17788ba6013e594ae94c5a0c27e83df3278b0660e", size = 27769 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/09/56376af256eab8cc5f8982a3b138d387136eca27fa1a8a68660e8ed59e4b/pywinpty-2.0.14-cp310-none-win_amd64.whl", hash = "sha256:0b149c2918c7974f575ba79f5a4aad58bd859a52fa9eb1296cc22aa412aa411f", size = 1397115 }, + { url = "https://files.pythonhosted.org/packages/be/e2/af1a99c0432e4e58c9ac8e334ee191790ec9793d33559189b9d2069bdc1d/pywinpty-2.0.14-cp311-none-win_amd64.whl", hash = "sha256:cf2a43ac7065b3e0dc8510f8c1f13a75fb8fde805efa3b8cff7599a1ef497bc7", size = 1397223 }, + { url = "https://files.pythonhosted.org/packages/ad/79/759ae767a3b78d340446efd54dd1fe4f7dafa4fc7be96ed757e44bcdba54/pywinpty-2.0.14-cp312-none-win_amd64.whl", hash = "sha256:55dad362ef3e9408ade68fd173e4f9032b3ce08f68cfe7eacb2c263ea1179737", size = 1397207 }, +] + +[[package]] +name = "pyyaml" +version = "6.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/95/a3fac87cb7158e231b5a6012e438c647e1a87f09f8e0d123acec8ab8bf71/PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", size = 184199 }, + { url = "https://files.pythonhosted.org/packages/c7/7a/68bd47624dab8fd4afbfd3c48e3b79efe09098ae941de5b58abcbadff5cb/PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", size = 171758 }, + { url = "https://files.pythonhosted.org/packages/49/ee/14c54df452143b9ee9f0f29074d7ca5516a36edb0b4cc40c3f280131656f/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", size = 718463 }, + { url = "https://files.pythonhosted.org/packages/4d/61/de363a97476e766574650d742205be468921a7b532aa2499fcd886b62530/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", size = 719280 }, + { url = "https://files.pythonhosted.org/packages/6b/4e/1523cb902fd98355e2e9ea5e5eb237cbc5f3ad5f3075fa65087aa0ecb669/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", size = 751239 }, + { url = "https://files.pythonhosted.org/packages/b7/33/5504b3a9a4464893c32f118a9cc045190a91637b119a9c881da1cf6b7a72/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", size = 695802 }, + { url = "https://files.pythonhosted.org/packages/5c/20/8347dcabd41ef3a3cdc4f7b7a2aff3d06598c8779faa189cdbf878b626a4/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", size = 720527 }, + { url = "https://files.pythonhosted.org/packages/be/aa/5afe99233fb360d0ff37377145a949ae258aaab831bde4792b32650a4378/PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", size = 144052 }, + { url = "https://files.pythonhosted.org/packages/b5/84/0fa4b06f6d6c958d207620fc60005e241ecedceee58931bb20138e1e5776/PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", size = 161774 }, + { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612 }, + { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040 }, + { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829 }, + { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167 }, + { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952 }, + { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301 }, + { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638 }, + { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850 }, + { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980 }, + { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873 }, + { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302 }, + { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154 }, + { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223 }, + { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542 }, + { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164 }, + { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611 }, + { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591 }, + { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338 }, +] + +[[package]] +name = "pyzmq" +version = "26.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "implementation_name == 'pypy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fd/05/bed626b9f7bb2322cdbbf7b4bd8f54b1b617b0d2ab2d3547d6e39428a48e/pyzmq-26.2.0.tar.gz", hash = "sha256:070672c258581c8e4f640b5159297580a9974b026043bd4ab0470be9ed324f1f", size = 271975 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1f/a8/9837c39aba390eb7d01924ace49d761c8dbe7bc2d6082346d00c8332e431/pyzmq-26.2.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:ddf33d97d2f52d89f6e6e7ae66ee35a4d9ca6f36eda89c24591b0c40205a3629", size = 1340058 }, + { url = "https://files.pythonhosted.org/packages/a2/1f/a006f2e8e4f7d41d464272012695da17fb95f33b54342612a6890da96ff6/pyzmq-26.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dacd995031a01d16eec825bf30802fceb2c3791ef24bcce48fa98ce40918c27b", size = 1008818 }, + { url = "https://files.pythonhosted.org/packages/b6/09/b51b6683fde5ca04593a57bbe81788b6b43114d8f8ee4e80afc991e14760/pyzmq-26.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89289a5ee32ef6c439086184529ae060c741334b8970a6855ec0b6ad3ff28764", size = 673199 }, + { url = "https://files.pythonhosted.org/packages/c9/78/486f3e2e824f3a645238332bf5a4c4b4477c3063033a27c1e4052358dee2/pyzmq-26.2.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5506f06d7dc6ecf1efacb4a013b1f05071bb24b76350832c96449f4a2d95091c", size = 911762 }, + { url = "https://files.pythonhosted.org/packages/5e/3b/2eb1667c9b866f53e76ee8b0c301b0469745a23bd5a87b7ee3d5dd9eb6e5/pyzmq-26.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ea039387c10202ce304af74def5021e9adc6297067f3441d348d2b633e8166a", size = 868773 }, + { url = "https://files.pythonhosted.org/packages/16/29/ca99b4598a9dc7e468b5417eda91f372b595be1e3eec9b7cbe8e5d3584e8/pyzmq-26.2.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a2224fa4a4c2ee872886ed00a571f5e967c85e078e8e8c2530a2fb01b3309b88", size = 868834 }, + { url = "https://files.pythonhosted.org/packages/ad/e5/9efaeb1d2f4f8c50da04144f639b042bc52869d3a206d6bf672ab3522163/pyzmq-26.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:28ad5233e9c3b52d76196c696e362508959741e1a005fb8fa03b51aea156088f", size = 1202861 }, + { url = "https://files.pythonhosted.org/packages/c3/62/c721b5608a8ac0a69bb83cbb7d07a56f3ff00b3991a138e44198a16f94c7/pyzmq-26.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:1c17211bc037c7d88e85ed8b7d8f7e52db6dc8eca5590d162717c654550f7282", size = 1515304 }, + { url = "https://files.pythonhosted.org/packages/87/84/e8bd321aa99b72f48d4606fc5a0a920154125bd0a4608c67eab742dab087/pyzmq-26.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b8f86dd868d41bea9a5f873ee13bf5551c94cf6bc51baebc6f85075971fe6eea", size = 1414712 }, + { url = "https://files.pythonhosted.org/packages/cd/cd/420e3fd1ac6977b008b72e7ad2dae6350cc84d4c5027fc390b024e61738f/pyzmq-26.2.0-cp310-cp310-win32.whl", hash = "sha256:46a446c212e58456b23af260f3d9fb785054f3e3653dbf7279d8f2b5546b21c2", size = 578113 }, + { url = "https://files.pythonhosted.org/packages/5c/57/73930d56ed45ae0cb4946f383f985c855c9b3d4063f26416998f07523c0e/pyzmq-26.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:49d34ab71db5a9c292a7644ce74190b1dd5a3475612eefb1f8be1d6961441971", size = 641631 }, + { url = "https://files.pythonhosted.org/packages/61/d2/ae6ac5c397f1ccad59031c64beaafce7a0d6182e0452cc48f1c9c87d2dd0/pyzmq-26.2.0-cp310-cp310-win_arm64.whl", hash = "sha256:bfa832bfa540e5b5c27dcf5de5d82ebc431b82c453a43d141afb1e5d2de025fa", size = 543528 }, + { url = "https://files.pythonhosted.org/packages/12/20/de7442172f77f7c96299a0ac70e7d4fb78cd51eca67aa2cf552b66c14196/pyzmq-26.2.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:8f7e66c7113c684c2b3f1c83cdd3376103ee0ce4c49ff80a648643e57fb22218", size = 1340639 }, + { url = "https://files.pythonhosted.org/packages/98/4d/5000468bd64c7910190ed0a6c76a1ca59a68189ec1f007c451dc181a22f4/pyzmq-26.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3a495b30fc91db2db25120df5847d9833af237546fd59170701acd816ccc01c4", size = 1008710 }, + { url = "https://files.pythonhosted.org/packages/e1/bf/c67fd638c2f9fbbab8090a3ee779370b97c82b84cc12d0c498b285d7b2c0/pyzmq-26.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77eb0968da535cba0470a5165468b2cac7772cfb569977cff92e240f57e31bef", size = 673129 }, + { url = "https://files.pythonhosted.org/packages/86/94/99085a3f492aa538161cbf27246e8886ff850e113e0c294a5b8245f13b52/pyzmq-26.2.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ace4f71f1900a548f48407fc9be59c6ba9d9aaf658c2eea6cf2779e72f9f317", size = 910107 }, + { url = "https://files.pythonhosted.org/packages/31/1d/346809e8a9b999646d03f21096428453465b1bca5cd5c64ecd048d9ecb01/pyzmq-26.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:92a78853d7280bffb93df0a4a6a2498cba10ee793cc8076ef797ef2f74d107cf", size = 867960 }, + { url = "https://files.pythonhosted.org/packages/ab/68/6fb6ae5551846ad5beca295b7bca32bf0a7ce19f135cb30e55fa2314e6b6/pyzmq-26.2.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:689c5d781014956a4a6de61d74ba97b23547e431e9e7d64f27d4922ba96e9d6e", size = 869204 }, + { url = "https://files.pythonhosted.org/packages/0f/f9/18417771dee223ccf0f48e29adf8b4e25ba6d0e8285e33bcbce078070bc3/pyzmq-26.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0aca98bc423eb7d153214b2df397c6421ba6373d3397b26c057af3c904452e37", size = 1203351 }, + { url = "https://files.pythonhosted.org/packages/e0/46/f13e67fe0d4f8a2315782cbad50493de6203ea0d744610faf4d5f5b16e90/pyzmq-26.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1f3496d76b89d9429a656293744ceca4d2ac2a10ae59b84c1da9b5165f429ad3", size = 1514204 }, + { url = "https://files.pythonhosted.org/packages/50/11/ddcf7343b7b7a226e0fc7b68cbf5a5bb56291fac07f5c3023bb4c319ebb4/pyzmq-26.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5c2b3bfd4b9689919db068ac6c9911f3fcb231c39f7dd30e3138be94896d18e6", size = 1414339 }, + { url = "https://files.pythonhosted.org/packages/01/14/1c18d7d5b7be2708f513f37c61bfadfa62161c10624f8733f1c8451b3509/pyzmq-26.2.0-cp311-cp311-win32.whl", hash = "sha256:eac5174677da084abf378739dbf4ad245661635f1600edd1221f150b165343f4", size = 576928 }, + { url = "https://files.pythonhosted.org/packages/3b/1b/0a540edd75a41df14ec416a9a500b9fec66e554aac920d4c58fbd5756776/pyzmq-26.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:5a509df7d0a83a4b178d0f937ef14286659225ef4e8812e05580776c70e155d5", size = 642317 }, + { url = "https://files.pythonhosted.org/packages/98/77/1cbfec0358078a4c5add529d8a70892db1be900980cdb5dd0898b3d6ab9d/pyzmq-26.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:c0e6091b157d48cbe37bd67233318dbb53e1e6327d6fc3bb284afd585d141003", size = 543834 }, + { url = "https://files.pythonhosted.org/packages/28/2f/78a766c8913ad62b28581777ac4ede50c6d9f249d39c2963e279524a1bbe/pyzmq-26.2.0-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:ded0fc7d90fe93ae0b18059930086c51e640cdd3baebdc783a695c77f123dcd9", size = 1343105 }, + { url = "https://files.pythonhosted.org/packages/b7/9c/4b1e2d3d4065be715e007fe063ec7885978fad285f87eae1436e6c3201f4/pyzmq-26.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:17bf5a931c7f6618023cdacc7081f3f266aecb68ca692adac015c383a134ca52", size = 1008365 }, + { url = "https://files.pythonhosted.org/packages/4f/ef/5a23ec689ff36d7625b38d121ef15abfc3631a9aecb417baf7a4245e4124/pyzmq-26.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55cf66647e49d4621a7e20c8d13511ef1fe1efbbccf670811864452487007e08", size = 665923 }, + { url = "https://files.pythonhosted.org/packages/ae/61/d436461a47437d63c6302c90724cf0981883ec57ceb6073873f32172d676/pyzmq-26.2.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4661c88db4a9e0f958c8abc2b97472e23061f0bc737f6f6179d7a27024e1faa5", size = 903400 }, + { url = "https://files.pythonhosted.org/packages/47/42/fc6d35ecefe1739a819afaf6f8e686f7f02a4dd241c78972d316f403474c/pyzmq-26.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea7f69de383cb47522c9c208aec6dd17697db7875a4674c4af3f8cfdac0bdeae", size = 860034 }, + { url = "https://files.pythonhosted.org/packages/07/3b/44ea6266a6761e9eefaa37d98fabefa112328808ac41aa87b4bbb668af30/pyzmq-26.2.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:7f98f6dfa8b8ccaf39163ce872bddacca38f6a67289116c8937a02e30bbe9711", size = 860579 }, + { url = "https://files.pythonhosted.org/packages/38/6f/4df2014ab553a6052b0e551b37da55166991510f9e1002c89cab7ce3b3f2/pyzmq-26.2.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e3e0210287329272539eea617830a6a28161fbbd8a3271bf4150ae3e58c5d0e6", size = 1196246 }, + { url = "https://files.pythonhosted.org/packages/38/9d/ee240fc0c9fe9817f0c9127a43238a3e28048795483c403cc10720ddef22/pyzmq-26.2.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6b274e0762c33c7471f1a7471d1a2085b1a35eba5cdc48d2ae319f28b6fc4de3", size = 1507441 }, + { url = "https://files.pythonhosted.org/packages/85/4f/01711edaa58d535eac4a26c294c617c9a01f09857c0ce191fd574d06f359/pyzmq-26.2.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:29c6a4635eef69d68a00321e12a7d2559fe2dfccfa8efae3ffb8e91cd0b36a8b", size = 1406498 }, + { url = "https://files.pythonhosted.org/packages/07/18/907134c85c7152f679ed744e73e645b365f3ad571f38bdb62e36f347699a/pyzmq-26.2.0-cp312-cp312-win32.whl", hash = "sha256:989d842dc06dc59feea09e58c74ca3e1678c812a4a8a2a419046d711031f69c7", size = 575533 }, + { url = "https://files.pythonhosted.org/packages/ce/2c/a6f4a20202a4d3c582ad93f95ee78d79bbdc26803495aec2912b17dbbb6c/pyzmq-26.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:2a50625acdc7801bc6f74698c5c583a491c61d73c6b7ea4dee3901bb99adb27a", size = 637768 }, + { url = "https://files.pythonhosted.org/packages/5f/0e/eb16ff731632d30554bf5af4dbba3ffcd04518219d82028aea4ae1b02ca5/pyzmq-26.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:4d29ab8592b6ad12ebbf92ac2ed2bedcfd1cec192d8e559e2e099f648570e19b", size = 540675 }, + { url = "https://files.pythonhosted.org/packages/53/fb/36b2b2548286e9444e52fcd198760af99fd89102b5be50f0660fcfe902df/pyzmq-26.2.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:706e794564bec25819d21a41c31d4df2d48e1cc4b061e8d345d7fb4dd3e94072", size = 906955 }, + { url = "https://files.pythonhosted.org/packages/77/8f/6ce54f8979a01656e894946db6299e2273fcee21c8e5fa57c6295ef11f57/pyzmq-26.2.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b435f2753621cd36e7c1762156815e21c985c72b19135dac43a7f4f31d28dd1", size = 565701 }, + { url = "https://files.pythonhosted.org/packages/ee/1c/bf8cd66730a866b16db8483286078892b7f6536f8c389fb46e4beba0a970/pyzmq-26.2.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:160c7e0a5eb178011e72892f99f918c04a131f36056d10d9c1afb223fc952c2d", size = 794312 }, + { url = "https://files.pythonhosted.org/packages/71/43/91fa4ff25bbfdc914ab6bafa0f03241d69370ef31a761d16bb859f346582/pyzmq-26.2.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c4a71d5d6e7b28a47a394c0471b7e77a0661e2d651e7ae91e0cab0a587859ca", size = 752775 }, + { url = "https://files.pythonhosted.org/packages/ec/d2/3b2ab40f455a256cb6672186bea95cd97b459ce4594050132d71e76f0d6f/pyzmq-26.2.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:90412f2db8c02a3864cbfc67db0e3dcdbda336acf1c469526d3e869394fe001c", size = 550762 }, +] + +[[package]] +name = "referencing" +version = "0.35.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "rpds-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/99/5b/73ca1f8e72fff6fa52119dbd185f73a907b1989428917b24cff660129b6d/referencing-0.35.1.tar.gz", hash = "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c", size = 62991 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/59/2056f61236782a2c86b33906c025d4f4a0b17be0161b63b70fd9e8775d36/referencing-0.35.1-py3-none-any.whl", hash = "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de", size = 26684 }, +] + +[[package]] +name = "requests" +version = "2.32.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, +] + +[[package]] +name = "rfc3339-validator" +version = "0.1.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/ea/a9387748e2d111c3c2b275ba970b735e04e15cdb1eb30693b6b5708c4dbd/rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b", size = 5513 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa", size = 3490 }, +] + +[[package]] +name = "rfc3986-validator" +version = "0.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/da/88/f270de456dd7d11dcc808abfa291ecdd3f45ff44e3b549ffa01b126464d0/rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055", size = 6760 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9", size = 4242 }, +] + [[package]] name = "rich" version = "13.9.3" @@ -1329,6 +2410,65 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9a/e2/10e9819cf4a20bd8ea2f5dabafc2e6bf4a78d6a0965daeb60a4b34d1c11f/rich-13.9.3-py3-none-any.whl", hash = "sha256:9836f5096eb2172c9e77df411c1b009bace4193d6a481d534fea75ebba758283", size = 242157 }, ] +[[package]] +name = "rpds-py" +version = "0.22.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/80/cce854d0921ff2f0a9fa831ba3ad3c65cee3a46711addf39a2af52df2cfd/rpds_py-0.22.3.tar.gz", hash = "sha256:e32fee8ab45d3c2db6da19a5323bc3362237c8b653c70194414b892fd06a080d", size = 26771 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/2a/ead1d09e57449b99dcc190d8d2323e3a167421d8f8fdf0f217c6f6befe47/rpds_py-0.22.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:6c7b99ca52c2c1752b544e310101b98a659b720b21db00e65edca34483259967", size = 359514 }, + { url = "https://files.pythonhosted.org/packages/8f/7e/1254f406b7793b586c68e217a6a24ec79040f85e030fff7e9049069284f4/rpds_py-0.22.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:be2eb3f2495ba669d2a985f9b426c1797b7d48d6963899276d22f23e33d47e37", size = 349031 }, + { url = "https://files.pythonhosted.org/packages/aa/da/17c6a2c73730d426df53675ff9cc6653ac7a60b6438d03c18e1c822a576a/rpds_py-0.22.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70eb60b3ae9245ddea20f8a4190bd79c705a22f8028aaf8bbdebe4716c3fab24", size = 381485 }, + { url = "https://files.pythonhosted.org/packages/aa/13/2dbacd820466aa2a3c4b747afb18d71209523d353cf865bf8f4796c969ea/rpds_py-0.22.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4041711832360a9b75cfb11b25a6a97c8fb49c07b8bd43d0d02b45d0b499a4ff", size = 386794 }, + { url = "https://files.pythonhosted.org/packages/6d/62/96905d0a35ad4e4bc3c098b2f34b2e7266e211d08635baa690643d2227be/rpds_py-0.22.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:64607d4cbf1b7e3c3c8a14948b99345eda0e161b852e122c6bb71aab6d1d798c", size = 423523 }, + { url = "https://files.pythonhosted.org/packages/eb/1b/d12770f2b6a9fc2c3ec0d810d7d440f6d465ccd8b7f16ae5385952c28b89/rpds_py-0.22.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e69b0a0e2537f26d73b4e43ad7bc8c8efb39621639b4434b76a3de50c6966e", size = 446695 }, + { url = "https://files.pythonhosted.org/packages/4d/cf/96f1fd75512a017f8e07408b6d5dbeb492d9ed46bfe0555544294f3681b3/rpds_py-0.22.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc27863442d388870c1809a87507727b799c8460573cfbb6dc0eeaef5a11b5ec", size = 381959 }, + { url = "https://files.pythonhosted.org/packages/ab/f0/d1c5b501c8aea85aeb938b555bfdf7612110a2f8cdc21ae0482c93dd0c24/rpds_py-0.22.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e79dd39f1e8c3504be0607e5fc6e86bb60fe3584bec8b782578c3b0fde8d932c", size = 410420 }, + { url = "https://files.pythonhosted.org/packages/33/3b/45b6c58fb6aad5a569ae40fb890fc494c6b02203505a5008ee6dc68e65f7/rpds_py-0.22.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e0fa2d4ec53dc51cf7d3bb22e0aa0143966119f42a0c3e4998293a3dd2856b09", size = 557620 }, + { url = "https://files.pythonhosted.org/packages/83/62/3fdd2d3d47bf0bb9b931c4c73036b4ab3ec77b25e016ae26fab0f02be2af/rpds_py-0.22.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fda7cb070f442bf80b642cd56483b5548e43d366fe3f39b98e67cce780cded00", size = 584202 }, + { url = "https://files.pythonhosted.org/packages/04/f2/5dced98b64874b84ca824292f9cee2e3f30f3bcf231d15a903126684f74d/rpds_py-0.22.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cff63a0272fcd259dcc3be1657b07c929c466b067ceb1c20060e8d10af56f5bf", size = 552787 }, + { url = "https://files.pythonhosted.org/packages/67/13/2273dea1204eda0aea0ef55145da96a9aa28b3f88bb5c70e994f69eda7c3/rpds_py-0.22.3-cp310-cp310-win32.whl", hash = "sha256:9bd7228827ec7bb817089e2eb301d907c0d9827a9e558f22f762bb690b131652", size = 220088 }, + { url = "https://files.pythonhosted.org/packages/4e/80/8c8176b67ad7f4a894967a7a4014ba039626d96f1d4874d53e409b58d69f/rpds_py-0.22.3-cp310-cp310-win_amd64.whl", hash = "sha256:9beeb01d8c190d7581a4d59522cd3d4b6887040dcfc744af99aa59fef3e041a8", size = 231737 }, + { url = "https://files.pythonhosted.org/packages/15/ad/8d1ddf78f2805a71253fcd388017e7b4a0615c22c762b6d35301fef20106/rpds_py-0.22.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d20cfb4e099748ea39e6f7b16c91ab057989712d31761d3300d43134e26e165f", size = 359773 }, + { url = "https://files.pythonhosted.org/packages/c8/75/68c15732293a8485d79fe4ebe9045525502a067865fa4278f178851b2d87/rpds_py-0.22.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:68049202f67380ff9aa52f12e92b1c30115f32e6895cd7198fa2a7961621fc5a", size = 349214 }, + { url = "https://files.pythonhosted.org/packages/3c/4c/7ce50f3070083c2e1b2bbd0fb7046f3da55f510d19e283222f8f33d7d5f4/rpds_py-0.22.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb4f868f712b2dd4bcc538b0a0c1f63a2b1d584c925e69a224d759e7070a12d5", size = 380477 }, + { url = "https://files.pythonhosted.org/packages/9a/e9/835196a69cb229d5c31c13b8ae603bd2da9a6695f35fe4270d398e1db44c/rpds_py-0.22.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bc51abd01f08117283c5ebf64844a35144a0843ff7b2983e0648e4d3d9f10dbb", size = 386171 }, + { url = "https://files.pythonhosted.org/packages/f9/8e/33fc4eba6683db71e91e6d594a2cf3a8fbceb5316629f0477f7ece5e3f75/rpds_py-0.22.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0f3cec041684de9a4684b1572fe28c7267410e02450f4561700ca5a3bc6695a2", size = 422676 }, + { url = "https://files.pythonhosted.org/packages/37/47/2e82d58f8046a98bb9497a8319604c92b827b94d558df30877c4b3c6ccb3/rpds_py-0.22.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7ef9d9da710be50ff6809fed8f1963fecdfecc8b86656cadfca3bc24289414b0", size = 446152 }, + { url = "https://files.pythonhosted.org/packages/e1/78/79c128c3e71abbc8e9739ac27af11dc0f91840a86fce67ff83c65d1ba195/rpds_py-0.22.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59f4a79c19232a5774aee369a0c296712ad0e77f24e62cad53160312b1c1eaa1", size = 381300 }, + { url = "https://files.pythonhosted.org/packages/c9/5b/2e193be0e8b228c1207f31fa3ea79de64dadb4f6a4833111af8145a6bc33/rpds_py-0.22.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a60bce91f81ddaac922a40bbb571a12c1070cb20ebd6d49c48e0b101d87300d", size = 409636 }, + { url = "https://files.pythonhosted.org/packages/c2/3f/687c7100b762d62186a1c1100ffdf99825f6fa5ea94556844bbbd2d0f3a9/rpds_py-0.22.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e89391e6d60251560f0a8f4bd32137b077a80d9b7dbe6d5cab1cd80d2746f648", size = 556708 }, + { url = "https://files.pythonhosted.org/packages/8c/a2/c00cbc4b857e8b3d5e7f7fc4c81e23afd8c138b930f4f3ccf9a41a23e9e4/rpds_py-0.22.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e3fb866d9932a3d7d0c82da76d816996d1667c44891bd861a0f97ba27e84fc74", size = 583554 }, + { url = "https://files.pythonhosted.org/packages/d0/08/696c9872cf56effdad9ed617ac072f6774a898d46b8b8964eab39ec562d2/rpds_py-0.22.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1352ae4f7c717ae8cba93421a63373e582d19d55d2ee2cbb184344c82d2ae55a", size = 552105 }, + { url = "https://files.pythonhosted.org/packages/18/1f/4df560be1e994f5adf56cabd6c117e02de7c88ee238bb4ce03ed50da9d56/rpds_py-0.22.3-cp311-cp311-win32.whl", hash = "sha256:b0b4136a252cadfa1adb705bb81524eee47d9f6aab4f2ee4fa1e9d3cd4581f64", size = 220199 }, + { url = "https://files.pythonhosted.org/packages/b8/1b/c29b570bc5db8237553002788dc734d6bd71443a2ceac2a58202ec06ef12/rpds_py-0.22.3-cp311-cp311-win_amd64.whl", hash = "sha256:8bd7c8cfc0b8247c8799080fbff54e0b9619e17cdfeb0478ba7295d43f635d7c", size = 231775 }, + { url = "https://files.pythonhosted.org/packages/75/47/3383ee3bd787a2a5e65a9b9edc37ccf8505c0a00170e3a5e6ea5fbcd97f7/rpds_py-0.22.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:27e98004595899949bd7a7b34e91fa7c44d7a97c40fcaf1d874168bb652ec67e", size = 352334 }, + { url = "https://files.pythonhosted.org/packages/40/14/aa6400fa8158b90a5a250a77f2077c0d0cd8a76fce31d9f2b289f04c6dec/rpds_py-0.22.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1978d0021e943aae58b9b0b196fb4895a25cc53d3956b8e35e0b7682eefb6d56", size = 342111 }, + { url = "https://files.pythonhosted.org/packages/7d/06/395a13bfaa8a28b302fb433fb285a67ce0ea2004959a027aea8f9c52bad4/rpds_py-0.22.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:655ca44a831ecb238d124e0402d98f6212ac527a0ba6c55ca26f616604e60a45", size = 384286 }, + { url = "https://files.pythonhosted.org/packages/43/52/d8eeaffab047e6b7b7ef7f00d5ead074a07973968ffa2d5820fa131d7852/rpds_py-0.22.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:feea821ee2a9273771bae61194004ee2fc33f8ec7db08117ef9147d4bbcbca8e", size = 391739 }, + { url = "https://files.pythonhosted.org/packages/83/31/52dc4bde85c60b63719610ed6f6d61877effdb5113a72007679b786377b8/rpds_py-0.22.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:22bebe05a9ffc70ebfa127efbc429bc26ec9e9b4ee4d15a740033efda515cf3d", size = 427306 }, + { url = "https://files.pythonhosted.org/packages/70/d5/1bab8e389c2261dba1764e9e793ed6830a63f830fdbec581a242c7c46bda/rpds_py-0.22.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3af6e48651c4e0d2d166dc1b033b7042ea3f871504b6805ba5f4fe31581d8d38", size = 442717 }, + { url = "https://files.pythonhosted.org/packages/82/a1/a45f3e30835b553379b3a56ea6c4eb622cf11e72008229af840e4596a8ea/rpds_py-0.22.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67ba3c290821343c192f7eae1d8fd5999ca2dc99994114643e2f2d3e6138b15", size = 385721 }, + { url = "https://files.pythonhosted.org/packages/a6/27/780c942de3120bdd4d0e69583f9c96e179dfff082f6ecbb46b8d6488841f/rpds_py-0.22.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:02fbb9c288ae08bcb34fb41d516d5eeb0455ac35b5512d03181d755d80810059", size = 415824 }, + { url = "https://files.pythonhosted.org/packages/94/0b/aa0542ca88ad20ea719b06520f925bae348ea5c1fdf201b7e7202d20871d/rpds_py-0.22.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f56a6b404f74ab372da986d240e2e002769a7d7102cc73eb238a4f72eec5284e", size = 561227 }, + { url = "https://files.pythonhosted.org/packages/0d/92/3ed77d215f82c8f844d7f98929d56cc321bb0bcfaf8f166559b8ec56e5f1/rpds_py-0.22.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0a0461200769ab3b9ab7e513f6013b7a97fdeee41c29b9db343f3c5a8e2b9e61", size = 587424 }, + { url = "https://files.pythonhosted.org/packages/09/42/cacaeb047a22cab6241f107644f230e2935d4efecf6488859a7dd82fc47d/rpds_py-0.22.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8633e471c6207a039eff6aa116e35f69f3156b3989ea3e2d755f7bc41754a4a7", size = 555953 }, + { url = "https://files.pythonhosted.org/packages/e6/52/c921dc6d5f5d45b212a456c1f5b17df1a471127e8037eb0972379e39dff4/rpds_py-0.22.3-cp312-cp312-win32.whl", hash = "sha256:593eba61ba0c3baae5bc9be2f5232430453fb4432048de28399ca7376de9c627", size = 221339 }, + { url = "https://files.pythonhosted.org/packages/f2/c7/f82b5be1e8456600395366f86104d1bd8d0faed3802ad511ef6d60c30d98/rpds_py-0.22.3-cp312-cp312-win_amd64.whl", hash = "sha256:d115bffdd417c6d806ea9069237a4ae02f513b778e3789a359bc5856e0404cc4", size = 235786 }, + { url = "https://files.pythonhosted.org/packages/8b/63/e29f8ee14fcf383574f73b6bbdcbec0fbc2e5fc36b4de44d1ac389b1de62/rpds_py-0.22.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:d48424e39c2611ee1b84ad0f44fb3b2b53d473e65de061e3f460fc0be5f1939d", size = 360786 }, + { url = "https://files.pythonhosted.org/packages/d3/e0/771ee28b02a24e81c8c0e645796a371350a2bb6672753144f36ae2d2afc9/rpds_py-0.22.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:24e8abb5878e250f2eb0d7859a8e561846f98910326d06c0d51381fed59357bd", size = 350589 }, + { url = "https://files.pythonhosted.org/packages/cf/49/abad4c4a1e6f3adf04785a99c247bfabe55ed868133e2d1881200aa5d381/rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b232061ca880db21fa14defe219840ad9b74b6158adb52ddf0e87bead9e8493", size = 381848 }, + { url = "https://files.pythonhosted.org/packages/3a/7d/f4bc6d6fbe6af7a0d2b5f2ee77079efef7c8528712745659ec0026888998/rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac0a03221cdb5058ce0167ecc92a8c89e8d0decdc9e99a2ec23380793c4dcb96", size = 387879 }, + { url = "https://files.pythonhosted.org/packages/13/b0/575c797377fdcd26cedbb00a3324232e4cb2c5d121f6e4b0dbf8468b12ef/rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb0c341fa71df5a4595f9501df4ac5abfb5a09580081dffbd1ddd4654e6e9123", size = 423916 }, + { url = "https://files.pythonhosted.org/packages/54/78/87157fa39d58f32a68d3326f8a81ad8fb99f49fe2aa7ad9a1b7d544f9478/rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf9db5488121b596dbfc6718c76092fda77b703c1f7533a226a5a9f65248f8ad", size = 448410 }, + { url = "https://files.pythonhosted.org/packages/59/69/860f89996065a88be1b6ff2d60e96a02b920a262d8aadab99e7903986597/rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b8db6b5b2d4491ad5b6bdc2bc7c017eec108acbf4e6785f42a9eb0ba234f4c9", size = 382841 }, + { url = "https://files.pythonhosted.org/packages/bd/d7/bc144e10d27e3cb350f98df2492a319edd3caaf52ddfe1293f37a9afbfd7/rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b3d504047aba448d70cf6fa22e06cb09f7cbd761939fdd47604f5e007675c24e", size = 409662 }, + { url = "https://files.pythonhosted.org/packages/14/2a/6bed0b05233c291a94c7e89bc76ffa1c619d4e1979fbfe5d96024020c1fb/rpds_py-0.22.3-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:e61b02c3f7a1e0b75e20c3978f7135fd13cb6cf551bf4a6d29b999a88830a338", size = 558221 }, + { url = "https://files.pythonhosted.org/packages/11/23/cd8f566de444a137bc1ee5795e47069a947e60810ba4152886fe5308e1b7/rpds_py-0.22.3-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:e35ba67d65d49080e8e5a1dd40101fccdd9798adb9b050ff670b7d74fa41c566", size = 583780 }, + { url = "https://files.pythonhosted.org/packages/8d/63/79c3602afd14d501f751e615a74a59040328da5ef29ed5754ae80d236b84/rpds_py-0.22.3-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:26fd7cac7dd51011a245f29a2cc6489c4608b5a8ce8d75661bb4a1066c52dfbe", size = 553619 }, + { url = "https://files.pythonhosted.org/packages/9f/2e/c5c1689e80298d4e94c75b70faada4c25445739d91b94c211244a3ed7ed1/rpds_py-0.22.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:177c7c0fce2855833819c98e43c262007f42ce86651ffbb84f37883308cb0e7d", size = 233338 }, +] + [[package]] name = "ruamel-yaml" version = "0.18.6" @@ -1353,6 +2493,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7f/b7/20c6f3c0b656fe609675d69bc135c03aac9e3865912444be6339207b6648/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f66efbc1caa63c088dead1c4170d148eabc9b80d95fb75b6c92ac0aad2437d76", size = 686712 }, { url = "https://files.pythonhosted.org/packages/cd/11/d12dbf683471f888d354dac59593873c2b45feb193c5e3e0f2ebf85e68b9/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:22353049ba4181685023b25b5b51a574bce33e7f51c759371a7422dcae5402a6", size = 663936 }, { url = "https://files.pythonhosted.org/packages/72/14/4c268f5077db5c83f743ee1daeb236269fa8577133a5cfa49f8b382baf13/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:932205970b9f9991b34f55136be327501903f7c66830e9760a8ffb15b07f05cd", size = 696580 }, + { url = "https://files.pythonhosted.org/packages/30/fc/8cd12f189c6405a4c1cf37bd633aa740a9538c8e40497c231072d0fef5cf/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a52d48f4e7bf9005e8f0a89209bf9a73f7190ddf0489eee5eb51377385f59f2a", size = 663393 }, { url = "https://files.pythonhosted.org/packages/80/29/c0a017b704aaf3cbf704989785cd9c5d5b8ccec2dae6ac0c53833c84e677/ruamel.yaml.clib-0.2.12-cp310-cp310-win32.whl", hash = "sha256:3eac5a91891ceb88138c113f9db04f3cebdae277f5d44eaa3651a4f573e6a5da", size = 100326 }, { url = "https://files.pythonhosted.org/packages/3a/65/fa39d74db4e2d0cd252355732d966a460a41cd01c6353b820a0952432839/ruamel.yaml.clib-0.2.12-cp310-cp310-win_amd64.whl", hash = "sha256:ab007f2f5a87bd08ab1499bdf96f3d5c6ad4dcfa364884cb4549aa0154b13a28", size = 118079 }, { url = "https://files.pythonhosted.org/packages/fb/8f/683c6ad562f558cbc4f7c029abcd9599148c51c54b5ef0f24f2638da9fbb/ruamel.yaml.clib-0.2.12-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:4a6679521a58256a90b0d89e03992c15144c5f3858f40d7c18886023d7943db6", size = 132224 }, @@ -1361,6 +2502,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/86/29/88c2567bc893c84d88b4c48027367c3562ae69121d568e8a3f3a8d363f4d/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:811ea1594b8a0fb466172c384267a4e5e367298af6b228931f273b111f17ef52", size = 703012 }, { url = "https://files.pythonhosted.org/packages/11/46/879763c619b5470820f0cd6ca97d134771e502776bc2b844d2adb6e37753/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cf12567a7b565cbf65d438dec6cfbe2917d3c1bdddfce84a9930b7d35ea59642", size = 704352 }, { url = "https://files.pythonhosted.org/packages/02/80/ece7e6034256a4186bbe50dee28cd032d816974941a6abf6a9d65e4228a7/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7dd5adc8b930b12c8fc5b99e2d535a09889941aa0d0bd06f4749e9a9397c71d2", size = 737344 }, + { url = "https://files.pythonhosted.org/packages/f0/ca/e4106ac7e80efbabdf4bf91d3d32fc424e41418458251712f5672eada9ce/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1492a6051dab8d912fc2adeef0e8c72216b24d57bd896ea607cb90bb0c4981d3", size = 714498 }, { url = "https://files.pythonhosted.org/packages/67/58/b1f60a1d591b771298ffa0428237afb092c7f29ae23bad93420b1eb10703/ruamel.yaml.clib-0.2.12-cp311-cp311-win32.whl", hash = "sha256:bd0a08f0bab19093c54e18a14a10b4322e1eacc5217056f3c063bd2f59853ce4", size = 100205 }, { url = "https://files.pythonhosted.org/packages/b4/4f/b52f634c9548a9291a70dfce26ca7ebce388235c93588a1068028ea23fcc/ruamel.yaml.clib-0.2.12-cp311-cp311-win_amd64.whl", hash = "sha256:a274fb2cb086c7a3dea4322ec27f4cb5cc4b6298adb583ab0e211a4682f241eb", size = 118185 }, { url = "https://files.pythonhosted.org/packages/48/41/e7a405afbdc26af961678474a55373e1b323605a4f5e2ddd4a80ea80f628/ruamel.yaml.clib-0.2.12-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:20b0f8dc160ba83b6dcc0e256846e1a02d044e13f7ea74a3d1d56ede4e48c632", size = 133433 }, @@ -1369,6 +2511,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/52/a9/d39f3c5ada0a3bb2870d7db41901125dbe2434fa4f12ca8c5b83a42d7c53/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:749c16fcc4a2b09f28843cda5a193e0283e47454b63ec4b81eaa2242f50e4ccd", size = 706497 }, { url = "https://files.pythonhosted.org/packages/b0/fa/097e38135dadd9ac25aecf2a54be17ddf6e4c23e43d538492a90ab3d71c6/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bf165fef1f223beae7333275156ab2022cffe255dcc51c27f066b4370da81e31", size = 698042 }, { url = "https://files.pythonhosted.org/packages/ec/d5/a659ca6f503b9379b930f13bc6b130c9f176469b73b9834296822a83a132/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:32621c177bbf782ca5a18ba4d7af0f1082a3f6e517ac2a18b3974d4edf349680", size = 745831 }, + { url = "https://files.pythonhosted.org/packages/db/5d/36619b61ffa2429eeaefaab4f3374666adf36ad8ac6330d855848d7d36fd/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b82a7c94a498853aa0b272fd5bc67f29008da798d4f93a2f9f289feb8426a58d", size = 715692 }, { url = "https://files.pythonhosted.org/packages/b1/82/85cb92f15a4231c89b95dfe08b09eb6adca929ef7df7e17ab59902b6f589/ruamel.yaml.clib-0.2.12-cp312-cp312-win32.whl", hash = "sha256:e8c4ebfcfd57177b572e2040777b8abc537cdef58a2120e830124946aa9b42c5", size = 98777 }, { url = "https://files.pythonhosted.org/packages/d7/8f/c3654f6f1ddb75daf3922c3d8fc6005b1ab56671ad56ffb874d908bfa668/ruamel.yaml.clib-0.2.12-cp312-cp312-win_amd64.whl", hash = "sha256:0467c5965282c62203273b838ae77c0d29d7638c8a4e3a1c8bdd3602c10904e4", size = 115523 }, ] @@ -1535,6 +2678,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/83/11/00d3c3dfc25ad54e731d91449895a79e4bf2384dc3ac01809010ba88f6d5/seaborn-0.13.2-py3-none-any.whl", hash = "sha256:636f8336facf092165e27924f223d3c62ca560b1f2bb5dff7ab7fad265361987", size = 294914 }, ] +[[package]] +name = "send2trash" +version = "1.8.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fd/3a/aec9b02217bb79b87bbc1a21bc6abc51e3d5dcf65c30487ac96c0908c722/Send2Trash-1.8.3.tar.gz", hash = "sha256:b18e7a3966d99871aefeb00cfbcfdced55ce4871194810fc71f4aa484b953abf", size = 17394 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/b0/4562db6223154aa4e22f939003cb92514c79f3d4dccca3444253fd17f902/Send2Trash-1.8.3-py3-none-any.whl", hash = "sha256:0c31227e0bd08961c7665474a3d1ef7193929fedda4233843689baa056be46c9", size = 18072 }, +] + [[package]] name = "session-info" version = "1.0.0" @@ -1580,6 +2732,29 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575 }, ] +[[package]] +name = "soupsieve" +version = "2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/ce/fbaeed4f9fb8b2daa961f90591662df6a86c1abf25c548329a86920aedfb/soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb", size = 101569 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/c2/fe97d779f3ef3b15f05c94a2f1e3d21732574ed441687474db9d342a7315/soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9", size = 36186 }, +] + +[[package]] +name = "stack-data" +version = "0.6.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "asttokens" }, + { name = "executing" }, + { name = "pure-eval" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", size = 44707 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521 }, +] + [[package]] name = "statsmodels" version = "0.13.2" @@ -1664,6 +2839,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b6/cb/b86984bed139586d01532a587464b5805f12e397594f19f931c4c2fbfa61/tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539", size = 28169 }, ] +[[package]] +name = "terminado" +version = "0.18.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ptyprocess", marker = "os_name != 'nt'" }, + { name = "pywinpty", marker = "os_name == 'nt'" }, + { name = "tornado" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8a/11/965c6fd8e5cc254f1fe142d547387da17a8ebfd75a3455f637c663fb38a0/terminado-0.18.1.tar.gz", hash = "sha256:de09f2c4b85de4765f7714688fff57d3e75bad1f909b589fde880460c753fd2e", size = 32701 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl", hash = "sha256:a4468e1b37bb318f8a86514f65814e1afc977cf29b3992a4500d9dd305dcceb0", size = 14154 }, +] + [[package]] name = "threadpoolctl" version = "3.5.0" @@ -1673,6 +2862,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4b/2c/ffbf7a134b9ab11a67b0cf0726453cedd9c5043a4fe7a35d1cefa9a1bcfb/threadpoolctl-3.5.0-py3-none-any.whl", hash = "sha256:56c1e26c150397e58c4926da8eeee87533b1e32bef131bd4bf6a2f45f3185467", size = 18414 }, ] +[[package]] +name = "tinycss2" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "webencodings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7a/fd/7a5ee21fd08ff70d3d33a5781c255cbe779659bd03278feb98b19ee550f4/tinycss2-1.4.0.tar.gz", hash = "sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7", size = 87085 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl", hash = "sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289", size = 26610 }, +] + [[package]] name = "tomli" version = "2.0.2" @@ -1682,6 +2883,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cf/db/ce8eda256fa131af12e0a76d481711abe4681b6923c27efb9a255c9e4594/tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38", size = 13237 }, ] +[[package]] +name = "tornado" +version = "6.4.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/59/45/a0daf161f7d6f36c3ea5fc0c2de619746cc3dd4c76402e9db545bd920f63/tornado-6.4.2.tar.gz", hash = "sha256:92bad5b4746e9879fd7bf1eb21dce4e3fc5128d71601f80005afa39237ad620b", size = 501135 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/26/7e/71f604d8cea1b58f82ba3590290b66da1e72d840aeb37e0d5f7291bd30db/tornado-6.4.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e828cce1123e9e44ae2a50a9de3055497ab1d0aeb440c5ac23064d9e44880da1", size = 436299 }, + { url = "https://files.pythonhosted.org/packages/96/44/87543a3b99016d0bf54fdaab30d24bf0af2e848f1d13d34a3a5380aabe16/tornado-6.4.2-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:072ce12ada169c5b00b7d92a99ba089447ccc993ea2143c9ede887e0937aa803", size = 434253 }, + { url = "https://files.pythonhosted.org/packages/cb/fb/fdf679b4ce51bcb7210801ef4f11fdac96e9885daa402861751353beea6e/tornado-6.4.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a017d239bd1bb0919f72af256a970624241f070496635784d9bf0db640d3fec", size = 437602 }, + { url = "https://files.pythonhosted.org/packages/4f/3b/e31aeffffc22b475a64dbeb273026a21b5b566f74dee48742817626c47dc/tornado-6.4.2-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c36e62ce8f63409301537222faffcef7dfc5284f27eec227389f2ad11b09d946", size = 436972 }, + { url = "https://files.pythonhosted.org/packages/22/55/b78a464de78051a30599ceb6983b01d8f732e6f69bf37b4ed07f642ac0fc/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", size = 437173 }, + { url = "https://files.pythonhosted.org/packages/79/5e/be4fb0d1684eb822c9a62fb18a3e44a06188f78aa466b2ad991d2ee31104/tornado-6.4.2-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:304463bd0772442ff4d0f5149c6f1c2135a1fae045adf070821c6cdc76980634", size = 437892 }, + { url = "https://files.pythonhosted.org/packages/f5/33/4f91fdd94ea36e1d796147003b490fe60a0215ac5737b6f9c65e160d4fe0/tornado-6.4.2-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:c82c46813ba483a385ab2a99caeaedf92585a1f90defb5693351fa7e4ea0bf73", size = 437334 }, + { url = "https://files.pythonhosted.org/packages/2b/ae/c1b22d4524b0e10da2f29a176fb2890386f7bd1f63aacf186444873a88a0/tornado-6.4.2-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:932d195ca9015956fa502c6b56af9eb06106140d844a335590c1ec7f5277d10c", size = 437261 }, + { url = "https://files.pythonhosted.org/packages/b5/25/36dbd49ab6d179bcfc4c6c093a51795a4f3bed380543a8242ac3517a1751/tornado-6.4.2-cp38-abi3-win32.whl", hash = "sha256:2876cef82e6c5978fde1e0d5b1f919d756968d5b4282418f3146b79b58556482", size = 438463 }, + { url = "https://files.pythonhosted.org/packages/61/cc/58b1adeb1bb46228442081e746fcdbc4540905c87e8add7c277540934edb/tornado-6.4.2-cp38-abi3-win_amd64.whl", hash = "sha256:908b71bf3ff37d81073356a5fadcc660eb10c1476ee6e2725588626ce7e5ca38", size = 438907 }, +] + [[package]] name = "tqdm" version = "4.66.6" @@ -1694,16 +2913,34 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/41/73/02342de9c2d20922115f787e101527b831c0cffd2105c946c4a4826bcfd4/tqdm-4.66.6-py3-none-any.whl", hash = "sha256:223e8b5359c2efc4b30555531f09e9f2f3589bcd7fdd389271191031b49b7a63", size = 78326 }, ] +[[package]] +name = "traitlets" +version = "5.14.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/eb/79/72064e6a701c2183016abbbfedaba506d81e30e232a68c9f0d6f6fcd1574/traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7", size = 161621 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359 }, +] + [[package]] name = "troppo" version = "0.1.0" -source = { git = "https://github.com/JoshLoecker/troppo?rev=update_dependencies#3b7302417d32e2fadaee356cc49e8c182a7dd531" } +source = { git = "https://github.com/JoshLoecker/troppo?rev=master#048edc8ebc8026aa7b04ef481b0637743f346d43" } dependencies = [ { name = "cobamp" }, { name = "cobra" }, { name = "xlrd" }, ] +[[package]] +name = "types-python-dateutil" +version = "2.9.0.20241206" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/60/47d92293d9bc521cd2301e423a358abfac0ad409b3a1606d8fbae1321961/types_python_dateutil-2.9.0.20241206.tar.gz", hash = "sha256:18f493414c26ffba692a72369fea7a154c502646301ebfe3d56a04b3767284cb", size = 13802 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/b3/ca41df24db5eb99b00d97f89d7674a90cb6b3134c52fb8121b6d8d30f15c/types_python_dateutil-2.9.0.20241206-py3-none-any.whl", hash = "sha256:e248a4bc70a486d3e3ec84d0dc30eec3a5f979d6e7ee4123ae043eedbb987f53", size = 14384 }, +] + [[package]] name = "typing-extensions" version = "4.12.2" @@ -1742,6 +2979,69 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3c/8f/671c0e1f2572ba625cbcc1faeba9435e00330c3d6962858711445cf1e817/umap_learn-0.5.7-py3-none-any.whl", hash = "sha256:6a7e0be2facfa365a5ed6588447102bdbef32a0ef449535c25c97ea7e680073c", size = 88815 }, ] +[[package]] +name = "uri-template" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/31/c7/0336f2bd0bcbada6ccef7aaa25e443c118a704f828a0620c6fa0207c1b64/uri-template-1.3.0.tar.gz", hash = "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7", size = 21678 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363", size = 11140 }, +] + +[[package]] +name = "urllib3" +version = "2.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ed/63/22ba4ebfe7430b76388e7cd448d5478814d3032121827c12a2cc287e2260/urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9", size = 300677 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/d9/5f4c13cecde62396b0d3fe530a50ccea91e7dfc1ccf0e09c228841bb5ba8/urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", size = 126338 }, +] + +[[package]] +name = "wcwidth" +version = "0.2.13" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6c/63/53559446a878410fc5a5974feb13d31d78d752eb18aeba59c7fef1af7598/wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5", size = 101301 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", size = 34166 }, +] + +[[package]] +name = "webcolors" +version = "24.11.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7b/29/061ec845fb58521848f3739e466efd8250b4b7b98c1b6c5bf4d40b419b7e/webcolors-24.11.1.tar.gz", hash = "sha256:ecb3d768f32202af770477b8b65f318fa4f566c22948673a977b00d589dd80f6", size = 45064 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/e8/c0e05e4684d13459f93d312077a9a2efbe04d59c393bc2b8802248c908d4/webcolors-24.11.1-py3-none-any.whl", hash = "sha256:515291393b4cdf0eb19c155749a096f779f7d909f7cceea072791cb9095b92e9", size = 14934 }, +] + +[[package]] +name = "webencodings" +version = "0.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/02/ae6ceac1baeda530866a85075641cec12989bd8d31af6d5ab4a3e8c92f47/webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923", size = 9721 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", size = 11774 }, +] + +[[package]] +name = "websocket-client" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e6/30/fba0d96b4b5fbf5948ed3f4681f7da2f9f64512e1d303f94b4cc174c24a5/websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da", size = 54648 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/84/44687a29792a70e111c5c477230a72c4b957d88d16141199bf9acb7537a3/websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526", size = 58826 }, +] + +[[package]] +name = "widgetsnbextension" +version = "4.0.13" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/56/fc/238c424fd7f4ebb25f8b1da9a934a3ad7c848286732ae04263661eb0fc03/widgetsnbextension-4.0.13.tar.gz", hash = "sha256:ffcb67bc9febd10234a362795f643927f4e0c05d9342c727b65d2384f8feacb6", size = 1164730 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/21/02/88b65cc394961a60c43c70517066b6b679738caf78506a5da7b88ffcb643/widgetsnbextension-4.0.13-py3-none-any.whl", hash = "sha256:74b2692e8500525cc38c2b877236ba51d34541e6385eeed5aec15a70f88a6c71", size = 2335872 }, +] + [[package]] name = "win32-setctime" version = "1.1.0" From 875d0a46667924b67b9121cf528df99d4daca9c1 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 13 Dec 2024 10:32:23 -0600 Subject: [PATCH 002/265] fix: import the correct variable --- main/como/merge_xomics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index 8dc2a6fd..0632d0df 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -16,8 +16,8 @@ from como import proteomics_gen, return_placeholder_data from como.combine_distributions import _combine_zscores -from como.custom_types import RNAPrepMethod from como.project import Config +from como.types import RNAPrepMethod from como.utils import split_gene_expression_data From 0c0d991eeee36221e4907364446c19394e48d9c3 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 13 Dec 2024 10:32:44 -0600 Subject: [PATCH 003/265] fix: divide by zero error; grouping too many items --- main/como/rnaseq_gen.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 364bd4c3..7a9a5041 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -237,8 +237,8 @@ def calculate_tpm(metrics: NamedMetrics) -> NamedMetrics: def calculate_fpkm(metrics: NamedMetrics) -> NamedMetrics: """Calculate the Fragments Per Kilobase of transcript per Million mapped reads (FPKM) for each sample in the metrics dictionary.""" # noqa: E501 - matrix_values = [] for study in metrics: + matrix_values = [] for sample in range(metrics[study].num_samples): layout = metrics[study].layout[sample] count_matrix: npt.NDArray = metrics[study].count_matrix.iloc[:, sample].values @@ -251,7 +251,7 @@ def calculate_fpkm(metrics: NamedMetrics) -> NamedMetrics: case LayoutMethod.paired_end: # FPKM mean_fragment_lengths = metrics[study].fragment_lengths[sample] # Ensure non-negative value - effective_length = [max(0, size - (mean_fragment_lengths + 1)) for size in gene_size] + effective_length = [max(1e-9, size - (mean_fragment_lengths + 1)) for size in gene_size] n = count_matrix.sum() fpkm = ((count_matrix + 1) * 1e9) / (np.array(effective_length) * n) matrix_values.append(fpkm) From fdb66dc06761b3a9eaa5ad961a921f9583b35757 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 17 Dec 2024 15:10:02 -0600 Subject: [PATCH 004/265] style: rearrange code --- main/como/merge_xomics.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index 0632d0df..829503b9 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -22,24 +22,24 @@ class _MergedHeaderNames: - PROTEOMICS = "prote" TRNASEQ = "trnaseq" MRNASEQ = "mrnaseq" SCRNASEQ = "scrnaseq" + PROTEOMICS = "prote" class _ExpressedHeaderNames: - PROTEOMICS = f"{_MergedHeaderNames.PROTEOMICS}_exp" TRNASEQ = f"{_MergedHeaderNames.TRNASEQ}_exp" MRNASEQ = f"{_MergedHeaderNames.MRNASEQ}_exp" SCRNASEQ = f"{_MergedHeaderNames.SCRNASEQ}_exp" + PROTEOMICS = f"{_MergedHeaderNames.PROTEOMICS}_exp" class _HighExpressionHeaderNames: - PROTEOMICS = f"{_MergedHeaderNames.PROTEOMICS}_high" TRNASEQ = f"{_MergedHeaderNames.TRNASEQ}_high" MRNASEQ = f"{_MergedHeaderNames.MRNASEQ}_high" SCRNASEQ = f"{_MergedHeaderNames.SCRNASEQ}_high" + PROTEOMICS = f"{_MergedHeaderNames.PROTEOMICS}_high" class AdjustmentMethod(Enum): From 43afd4f65d08be342a736e4dbe0ab7bd0a4c4c03 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 17 Dec 2024 15:11:36 -0600 Subject: [PATCH 005/265] refactor: remove command line interface --- main/como/merge_xomics.py | 248 -------------------------------------- 1 file changed, 248 deletions(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index 829503b9..cc875044 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -58,41 +58,6 @@ def from_string(cls, value: str) -> AdjustmentMethod: return cls(value) -@dataclass -class _Arguments: - trnaseq_filename: str - mrnaseq_filename: str - scrnaseq_filename: str - proteomics_filename: str - expression_requirement: str | int - adjustment_method: AdjustmentMethod - no_high_confidence: bool - no_na: bool - merge_zfpkm_distribution: bool - keep_transcriptomics_scores: bool - trna_weight: int - mrna_weight: int - scrna_weight: int - proteomics_weight: int - custom_expression_filename: str - - def __post_init__(self): - if self.expression_requirement.isdigit(): - self.expression_requirement = int(self.expression_requirement) - if self.expression_requirement < 1: - logger.warning( - f"Expression requirement should be at least 1, setting to 1 now. Got {self.expression_requirement}" - ) - self.expression_requirement = 1 - elif self.expression_requirement != "default": - raise ValueError( - f"Expression requirement should be an integer or 'default', got {self.expression_requirement}" - ) - - if self.adjustment_method.value.lower() not in ["progressive", "regressive", "flat", "custom"]: - raise ValueError("Adjust method must be either 'progressive', 'regressive', 'flat', or 'custom'") - - def _load_rnaseq_tests(filename, context_name, prep_method: RNAPrepMethod) -> tuple[str, pd.DataFrame]: """Load rnaseq results. @@ -627,225 +592,12 @@ async def merge_xomics( merge_zfpkm_distribution, keep_transcriptomics_score, ) - - -def _parse_args() -> _Arguments: - """Merge expression tables of multiple sources, (RNA-seq, proteomics) into one list. - - User can specify the number of sources with an active gene in order for it to be considered active in the model. - Otherwise, it defaults to the number of sources provided. High-confidence genes from any source will be considered - active in the model, regardless of agreement with other sources. - """ - parser = argparse.ArgumentParser( - prog="merge_xomics.py", - description="Merge expression tables of multiple sources (RNA-seq, proteomics) into one", - epilog="For additional help, please post questions/issues in the MADRID GitHub repo at " - "https://github.com/HelikarLab/MADRID or email babessell@gmail.com", - ) - - parser.add_argument( - "-d", - "--merge-zfpkm-distribution", - action="store_true", - required=False, - default=False, - dest="merge_zfpkm_distribution", - help="Flag to merge zFPKM distributions. Required if using iMAT reconstruction algorithm in " - "create_context_specific_model.py. Must have run rnaseq_gen.py with 'zFPKM' as " - "'--technique'. If --proteomics-config-file is given will merge proteomics distributions " - "with zFPKM distributions using a weighted scheme.", ) - - parser.add_argument( - "-k", - "--keep-transcriptomics-scores", - action="store_true", - required=False, - default=True, - dest="keep_transcriptomics_scores", - help="When merging z-score distributions of expression, if using both protein abundance and transcipt zFPKM " - "flag true if you wish to keep z-score of genes with no protein data, flag false if you wish to discard " - "and treat as no expression", ) - - parser.add_argument( - "-t", - "--total-rnaseq-config-file", - type=str, - required=False, - default=None, - dest="trnaseq_filename", - help="Name of total RNA-seq config .xlsx file in the /main/data/config_files/.", ) - parser.add_argument( - "-m", - "--mrnaseq-config-file", - type=str, - required=False, - default=None, - dest="mrnaseq_filename", - help="Name of mRNA-seq config .xlsx file in the /main/data/config_files/.", ) - - parser.add_argument( - "-s", - "--scrnaseq-config-file", - type=str, - required=False, - default=None, - dest="scrnaseq_filename", - help="Name of RNA-seq config .xlsx file in the /main/data/config_files/.", ) - - parser.add_argument( - "-p", - "--proteomics-config-file", - type=str, - required=False, - default=None, - dest="proteomics_filename", - help="Name of proteomics config .xlsx file in the /main/data/config_files/.", ) - - parser.add_argument( - "-e", - "--expression-requirement", - type=str, - required=False, - default=None, - dest="expression_requirement", - help="Number of sources with active gene for it to be considered active " - "even if it is not a high confidence-gene", ) - - parser.add_argument( - "-r", - "--requirement-adjust", - type=str, - required=False, - default="flat", - dest="adjustment_method", - help="Technique to adjust expression requirement based on differences in number of provided data source types.", - ) - - parser.add_argument( - "-c", - "--custom-requirement-file", - required="custom" in sys.argv, # required if --requriement-adjust is "custom", - dest="custom_expression_filename", - default=None, - help="Name of .xlsx file where first column is context names and " - "second column is expression requirement for that context", - ) - - parser.add_argument( - "--no-hc", - "--no-high-confidence", - action="store_true", - required=False, - default=False, - dest="no_high_confidence", - help="Prevent high-confidence genes forcing a gene to be used in final model, " - "irrespective of other other data sources", ) - - parser.add_argument( - "-na", - "--no-na-adjustment", - action="store_true", - required=False, - default=False, - dest="no_na", - help="Prevent genes missing in a data source library, but present in others from " - "subtracting 1 from the expression requirement per data source that gene is missing in", - ) - - parser.add_argument( - "-tw", - "--total-rnaseq-weight", - required=False, - default=1, - type=float, - dest="trna_weight", - help="Total RNA-seq weight for merging zFPKM distribution", - ) - - parser.add_argument( - "-mw", - "--mrnaseq-weight", - required=False, - default=1, - type=float, - dest="mrna_weight", - help="PolyA enriched (messenger) RNA-seq weight for merging zFPKM distribution", - ) - - parser.add_argument( - "-sw", - "--single-cell-rnaseq-weight", - required=False, - default=1, - type=float, - dest="scrna_weight", - help="Single-cell RNA-seq weight for merging zFPKM distribution", - ) - - parser.add_argument( - "-pw", - "--protein-weight", - required=False, - default=2, - type=float, - dest="proteomics_weight", - help="Proteomics weight for merging z-score distribution", - ) - args = parser.parse_args() - args.adjustment_method = AdjustmentMethod.from_string(str(args.adjustment_method)) - return _Arguments(**vars(args)) - - -if __name__ == "__main__": - import asyncio - - args = _parse_args() - config = Config() - - # read custom expression requirment file if used - if args.custom_expression_filename: - custom_filepath = config.data_dir / args.custom_expression_filename - custom_df = pd.read_excel(custom_filepath, sheet_name=0) - custom_df.columns = ["context", "req"] - else: - custom_df = pd.DataFrame([]) - - def_exp_req = sum( - test is None - for test in [ - args.trnaseq_filename, - args.mrnaseq_filename, - args.scrnaseq_filename, - args.proteomics_filename, - ] - ) - - asyncio.run( - merge_xomics( - trnaseq_filepath=args.trnaseq_filename, - mrnaseq_filepath=args.mrnaseq_filename, - scrnaseq_filepath=args.scrnaseq_filename, - proteomics_filepath=args.proteomics_filename, - trna_weight=args.trna_weight, - mrna_weight=args.mrna_weight, - scrna_weight=args.scrna_weight, - proteomics_weight=args.proteomics_weight, - expression_requirement=args.expression_requirement, - adjust_method=args.adjustment_method, - no_high_confidence=args.no_high_confidence, - no_na=args.no_na, - merge_zfpkm_distribution=args.merge_zfpkm_distribution, - keep_transcriptomics_score=args.keep_transcriptomics_scores, - ) - ) - - logger.success("Finished merging!") From ad6e68db4410d2e6cef8e4f9abd818ada6cee148 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 17 Dec 2024 15:12:38 -0600 Subject: [PATCH 006/265] feat: use MyGene instead of BioDBNet --- main/como/merge_xomics.py | 76 ++++++++++----------------------------- 1 file changed, 19 insertions(+), 57 deletions(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index cc875044..7bd60e9d 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -11,7 +11,7 @@ import numpy as np import pandas as pd -from fast_bioservices import BioDBNet, Input, Output +from fast_bioservices.biothings.mygene import MyGene from loguru import logger from como import proteomics_gen, return_placeholder_data @@ -182,7 +182,7 @@ def _merge_logical_table(df: pd.DataFrame): return df -async def _get_transcriptmoic_details(merged_df: pd.DataFrame) -> pd.DataFrame: +async def _get_transcriptmoic_details(merged_df: pd.DataFrame, taxon_id: int) -> pd.DataFrame: """Get details of transcriptomic data. This function will get the following details of transcriptomic data: @@ -198,6 +198,7 @@ async def _get_transcriptmoic_details(merged_df: pd.DataFrame) -> pd.DataFrame: """ # If _ExpressedHeaderNames.PROTEOMICS.value is in the dataframe, lower the required expression by 1 # We are only trying to get details for transcriptomic data + transcriptomic_df: pd.DataFrame = merged_df.copy() if _ExpressedHeaderNames.PROTEOMICS in merged_df.columns: # Get the number of sources required for a gene to be marked "expressed" required_expression = merged_df["Required"].iloc[0] @@ -225,62 +226,23 @@ async def _get_transcriptmoic_details(merged_df: pd.DataFrame) -> pd.DataFrame: "Active", ] = 1 - else: - transcriptomic_df: pd.DataFrame = merged_df.copy() - - biodbnet = BioDBNet() - gene_details: pd.DataFrame = await biodbnet.async_db2db( - values=transcriptomic_df.index.astype(str).values.tolist(), - input_db=Input.GENE_ID, - output_db=[ - Output.GENE_SYMBOL, - Output.ENSEMBL_GENE_INFO, - Output.GENE_INFO, - ], - ) - gene_details["entrez_gene_id"] = gene_details.index - gene_details.reset_index(drop=True, inplace=True) - - # Apply regex to search for "[Description: XXXXXX]" and retrieve the XXXXXX - # It excludes the square brackets and "Description: ", and only returns the description - # descriptions: list[str] = [ - gene_details["description"] = [ - i.group(1) if isinstance(i, re.Match) else "No Description Available" - for i in gene_details["Ensembl Gene Info"].apply(lambda x: re.search(r"\[Description: (.*)\]", x)) - ] - - gene_details["gene_info_type"] = [ - i.group(1) if isinstance(i, re.Match) else "None" - for i in gene_details["Gene Info"].apply(lambda x: re.search(r"\[Gene Type: (.*)\]", x)) - ] - gene_details["ensembl_info_type"] = [ - i.group(1) if isinstance(i, re.Match) else "None" - for i in gene_details["Ensembl Gene Info"].apply(lambda x: re.search(r"\[Gene Type: (.*)\]", x)) - ] - - gene_type: list[str] = [] - row: pd.DataFrame - for row in gene_details.itertuples(): - if row.gene_info_type != "None": - gene_type.append(row.gene_info_type) - elif row.ensembl_info_type != "None": - gene_type.append(row.ensembl_info_type) - else: - gene_type.append("No Gene Type Available") - gene_details["gene_type"] = gene_type - - # Drop gene_info_type and ensembl_info_type columns - gene_details.drop( - columns=[ - "Ensembl Gene Info", - "Gene Info", - "gene_info_type", - "ensembl_info_type", - ], - inplace=True, + my_gene = MyGene() + gene_details: pd.DataFrame = pd.DataFrame( + data=pd.NA, + columns=["entrez_gene_id", "gene_symbol", "description", "gene_type"], + index=list(range(len(transcriptomic_df))), ) - gene_details.rename(columns={"entrez_gene_id": "Entrez Gene ID"}, inplace=True) - + for i, detail in enumerate( + await my_gene.query( + items=transcriptomic_df["entrez_gene_id"].tolist(), + taxon=taxon_id, + scopes="entrezgene", + ) + ): + gene_details.at[i, "entrez_gene_id"] = detail["entrezgene"] + gene_details.at[i, "gene_symbol"] = detail["symbol"] + gene_details.at[i, "description"] = detail["name"] + gene_details.at[i, "gene_type"] = detail["type_of_gene"] return gene_details From 59e4cfea3ea8264e9a7516819a0af5ff9b183100 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 17 Dec 2024 15:12:58 -0600 Subject: [PATCH 007/265] refactor: import required modules --- main/como/merge_xomics.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index 7bd60e9d..c13ab702 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -1,11 +1,5 @@ from __future__ import annotations -import argparse -import json -import re -import sys -from collections import Counter -from dataclasses import dataclass from enum import Enum from pathlib import Path @@ -14,11 +8,17 @@ from fast_bioservices.biothings.mygene import MyGene from loguru import logger -from como import proteomics_gen, return_placeholder_data -from como.combine_distributions import _combine_zscores +from como import return_placeholder_data +from como.combine_distributions import ( + _BatchEntry, + _BatchNames, + _InputMatrices, + _new_combine_zscores, + _OutputCombinedSourceFilepath, + _SourceWeights, +) +from como.data_types import RNAPrepMethod from como.project import Config -from como.types import RNAPrepMethod -from como.utils import split_gene_expression_data class _MergedHeaderNames: From 7a028f9571b69201c150326b18a017132dc00565 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 17 Dec 2024 15:14:06 -0600 Subject: [PATCH 008/265] style: use pythonic variable names --- main/como/merge_xomics.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index c13ab702..23b45d62 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -201,11 +201,11 @@ async def _get_transcriptmoic_details(merged_df: pd.DataFrame, taxon_id: int) -> transcriptomic_df: pd.DataFrame = merged_df.copy() if _ExpressedHeaderNames.PROTEOMICS in merged_df.columns: # Get the number of sources required for a gene to be marked "expressed" - required_expression = merged_df["Required"].iloc[0] + required_expression = merged_df["required"].iloc[0] # Subtract 1 from merged_df["TotalExpressed"] if the current value is greater than or equal to 1 # This is done to take into account the removal of proteomic expression - merged_df["TotalExpressed"] = merged_df["TotalExpressed"].apply(lambda x: x - 1 if x >= 1 else x) + merged_df["total_expressed"] = merged_df["total_expressed"].apply(lambda x: x - 1 if x >= 1 else x) # Subtract required_expression by 1 if it is greater than 1 if required_expression > 1: @@ -222,8 +222,8 @@ async def _get_transcriptmoic_details(merged_df: pd.DataFrame, taxon_id: int) -> # Must recalculate TotalExpressed because proteomic data was removed # If the TotalExpressed column is less than the Required column, set active to 1, otherwise set it to 0 transcriptomic_df.loc[ - transcriptomic_df["TotalExpressed"] >= transcriptomic_df["Required"], - "Active", + transcriptomic_df["total_expressed"] >= transcriptomic_df["required"], + "active", ] = 1 my_gene = MyGene() @@ -332,16 +332,16 @@ async def _merge_xomics( ) merge_data = prote_data if merge_data is None else merge_data.join(prote_data, how="outer") - if merge_data is None: + if merge_data.empty: logger.critical( f"No data is available for the '{context_name}' context. If this is intentional, ignore this error." ) return {} - merge_data = _merge_logical_table(merge_data) + merge_data = _merge_logical_table(merge_data) num_sources = len(expression_list) - merge_data["Active"] = 0 - merge_data["Required"] = 0 + merge_data["active"] = 0 + merge_data["required"] = 0 if no_na: # dont adjust for na values merge_data.loc[:, "Required"] = merge_data[expression_list].apply( @@ -357,8 +357,6 @@ async def _merge_xomics( ) # count number of sources gene is active in. Set to active in final output if at least adjusted expression reqirmnt - merge_data["TotalExpressed"] = merge_data[expression_list].sum(axis=1) - merge_data.loc[merge_data["TotalExpressed"] >= merge_data["Required"], "Active"] = 1 if not no_hc: # set genes that are high-confidence in at least one data source to active merge_data.loc[merge_data[high_confidence_list].sum(axis=1) > 0, "Active"] = 1 @@ -375,6 +373,8 @@ async def _merge_xomics( split_entrez = split_gene_expression_data(merge_data) split_entrez.to_csv(filepath, index_label="entrez_gene_id") files_dict = {context_name: filepath.as_posix()} + merge_data["total_expressed"] = merge_data[expression_list].sum(axis=1) + merge_data.loc[merge_data["total_expressed"] >= merge_data["required"], "active"] = 1 transcriptomic_details = await _get_transcriptmoic_details(merge_data) transcriptomic_details_filepath = filepath.parent / f"TranscriptomicDetails_{context_name}.csv" From 35de93e36cedab29d4a020ca5f1823418165e25c Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 17 Dec 2024 15:15:17 -0600 Subject: [PATCH 009/265] refactor: remove encompassing for loop Only a single context can be processed at a time; if more contexts need to be processed, merge xomics should be wrapped in a for loop --- main/como/merge_xomics.py | 207 ++++++++++++++++++++------------------ 1 file changed, 109 insertions(+), 98 deletions(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index 23b45d62..87183a44 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -385,120 +385,131 @@ async def _merge_xomics( return files_dict -async def _handle_context_batch( # noqa: C901 - trnaseq_file: Path | None, - mrnaseq_file: Path | None, - scrnaseq_file: Path | None, - proteomics_file: Path | None, - tweight: float, - mweight: float, - sweight: float, - pweight: float, +async def _process( + *, + context_name: str, + trna_matrix: pd.DataFrame | None, + mrna_matrix: pd.DataFrame | None, + scrna_matrix: pd.DataFrame | None, + proteomic_matrix: pd.DataFrame | None, + trna_boolean_matrix: pd.DataFrame | None, + mrna_boolean_matrix: pd.DataFrame | None, + scrna_boolean_matrix: pd.DataFrame | None, + proteomic_boolean_matrix: pd.DataFrame | None, + trna_batches: dict[int, list[str]], + mrna_batches: dict[int, list[str]], + scrna_batches: dict[int, list[str]], + proteomic_batches: dict[int, list[str]], + trna_weight: int, + mrna_weight: int, + scrna_weight: int, + proteomic_weight: int, + taxon_id: int, + minimum_source_expression: int, expression_requirement: int, + weighted_z_floor: int, + weighted_z_ceiling: int, adjust_method: AdjustmentMethod, - no_hc: bool, - no_na: bool, merge_zfpkm_distribution: bool, keep_gene_score: bool, + force_activate_high_confidence: bool, + adjust_for_missing_sources: bool, + output_merge_activity_filepath: Path, + output_transcriptomic_details_filepath: Path, + output_trna_activity_filepath: Path | None, + output_mrna_activity_filepath: Path | None, + output_scrna_activity_filepath: Path | None, + output_proteomic_activity_filepath: Path | None, + output_final_model_scores_filepath: Path, + output_figure_dirpath: Path | None, ): """Merge different data sources for each context type.""" - if all(file is None for file in [trnaseq_file, mrnaseq_file, scrnaseq_file, proteomics_file]): - raise ValueError("No configuration file was passed!") - - config = Config() - sheet_names = [] - for file in [trnaseq_file, mrnaseq_file, scrnaseq_file, proteomics_file]: - if file is not None: - config_filepath = config.config_dir / file - try: - xl = pd.ExcelFile(config_filepath, engine="openpyxl") - except Exception as e: - raise ValueError(f"Unable to read file '{config_filepath}'") from e - sheet_names += xl.sheet_names - - use_trna = trnaseq_file is not None - use_mrna = mrnaseq_file is not None - use_scrna = scrnaseq_file is not None - use_proteins = proteomics_file is not None - - counts = Counter(sheet_names) - sheet_names = sorted(set(sheet_names)) - logger.info("Beginning to merge data within contexts") - dict_list = {} - - max_inputs = max(counts.values()) - min_inputs = min(counts.values()) + num_sources = sum(1 for source in [trna_matrix, mrna_matrix, scrna_matrix, proteomic_matrix] if source is not None) if merge_zfpkm_distribution: - logger.debug("Using zFPKM distribution for merging") - _combine_zscores( - working_dir=config.result_dir.as_posix(), - context_names=sheet_names, - global_use_mrna=use_mrna, - global_use_trna=use_trna, - global_use_scrna=use_scrna, - global_use_proteins=use_proteins, + _new_combine_zscores( + context_name=context_name, + input_matrices=_InputMatrices( + trna=trna_matrix, + mrna=mrna_matrix, + scrna=scrna_matrix, + proteomics=proteomic_matrix, + ), + batch_names=_BatchNames( + trna=[_BatchEntry(batch_num=n, sample_names=s) for n, s in trna_batches.items()], + mrna=[_BatchEntry(batch_num=n, sample_names=s) for n, s in mrna_batches.items()], + scrna=[_BatchEntry(batch_num=n, sample_names=s) for n, s in scrna_batches.items()], + proteomics=[_BatchEntry(batch_num=n, sample_names=s) for n, s in proteomic_batches.items()], + ), + source_weights=_SourceWeights( + trna=trna_weight, + mrna=mrna_weight, + scrna=scrna_weight, + proteomics=proteomic_weight, + ), + output_filepaths=_OutputCombinedSourceFilepath( + trna=output_trna_activity_filepath, + mrna=output_mrna_activity_filepath, + scrna=output_scrna_activity_filepath, + proteomics=output_proteomic_activity_filepath, + ), + output_figure_dirpath=output_figure_dirpath, + output_final_model_scores=output_final_model_scores_filepath, keep_gene_scores=keep_gene_score, - global_trna_weight=tweight, - global_mrna_weight=mweight, - global_scrna_weight=sweight, - global_protein_weight=pweight, + weighted_z_floor=weighted_z_floor, + weighted_z_ceiling=weighted_z_ceiling, ) - for context_name in sheet_names: - num_sources = counts[context_name] - match adjust_method: - case AdjustmentMethod.PROGRESSIVE: - adjusted_expression_requirement = (num_sources - min_inputs) + expression_requirement - case AdjustmentMethod.REGRESSIVE: - adjusted_expression_requirement = expression_requirement - (max_inputs - num_sources) - case AdjustmentMethod.FLAT: - adjusted_expression_requirement = expression_requirement - case _: - adjusted_expression_requirement = int( - custom_df.iloc[custom_df["context"] == context_name, "req"].iloc[0] - ) - - if adjusted_expression_requirement != expression_requirement: - logger.debug( - f"Expression requirement of '{expression_requirement}' adjusted to " - f"'{adjusted_expression_requirement}' using '{adjust_method.value}' adjustment method " - f"for '{context_name}'." - ) + # the more data sources available, the higher the expression requirement for the gene + if adjust_method == AdjustmentMethod.PROGRESSIVE: + adjusted_expression_requirement = (num_sources - minimum_source_expression) + expression_requirement + # the more data sources available, the lower the expression requirement for the gene + elif adjust_method == AdjustmentMethod.REGRESSIVE: + # we use a hardcoded 4 here because that is the maximum number of contexts available + # (trna, mrna, scrna, and proteomics is 4 sources) + adjusted_expression_requirement = expression_requirement - (4 - num_sources) + elif adjust_method == AdjustmentMethod.FLAT: + adjusted_expression_requirement = expression_requirement + + if adjusted_expression_requirement != expression_requirement: + logger.debug( + f"Expression requirement of '{expression_requirement}' adjusted to " + f"'{adjusted_expression_requirement}' using '{adjust_method.value}' adjustment method " + f"for '{context_name}'." + ) - if adjusted_expression_requirement > num_sources: - logger.warning( - f"Expression requirement for {context_name} was calculated to be greater " - f"than max number of input data sources. " - f"Will be force changed to {num_sources} to prevent output from having 0 active genes. " - f"Consider lowering the expression requirement or changing the adjustment method." - ) - adjusted_expression_requirement = num_sources + if adjusted_expression_requirement > num_sources: + logger.warning( + f"Expression requirement for {context_name} was calculated to be greater " + f"than max number of input data sources. " + f"Will be force changed to {num_sources} to prevent output from having 0 active genes. " + f"Consider lowering the expression requirement or changing the adjustment method." + ) + adjusted_expression_requirement = num_sources - if adjusted_expression_requirement < 1: # never allow expression requirement to be less than one - logger.warning( - f"Expression requirement for {context_name} was calculated to be less than 1. " - "Will be changed to 1 to prevent output from having 0 active genes. " - ) - adjusted_expression_requirement = 1 - - files_dict = await _merge_xomics( - context_name, - expression_requirement=adjusted_expression_requirement, - proteomics_file=proteomics_file, - trnaseq_file=trnaseq_file, - mrnaseq_file=mrnaseq_file, - scrnaseq_file=scrnaseq_file, - no_hc=no_hc, - no_na=no_na, + if adjusted_expression_requirement < 1: # never allow expression requirement to be less than one + logger.warning( + f"Expression requirement for {context_name} was calculated to be less than 1. " + "Will be changed to 1 to prevent output from having 0 active genes. " ) + adjusted_expression_requirement = 1 + + await _new_merge_xomics( + context_name=context_name, + expression_requirement=adjusted_expression_requirement, + trna_boolean_matrix=trna_boolean_matrix, + mrna_boolean_matrix=mrna_boolean_matrix, + scrna_boolean_matrix=scrna_boolean_matrix, + proteomic_boolean_matrix=proteomic_boolean_matrix, + output_merged_filepath=output_merge_activity_filepath, + output_gene_activity_filepath=output_final_model_scores_filepath, + output_transcriptomic_details_filepath=output_transcriptomic_details_filepath, + taxon_id=taxon_id, + force_activate_high_confidence=force_activate_high_confidence, + adjust_for_missing_sources=adjust_for_missing_sources, + ) - dict_list |= files_dict - files_json = config.result_dir / "step1_results_files.json" - files_json.parent.mkdir(parents=True, exist_ok=True) - with files_json.open("w") as f: - json.dump(dict_list, f) # type: ignore return From 3adf9c686266ebd6a277942d4575fa6d3023ef1c Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 17 Dec 2024 15:16:13 -0600 Subject: [PATCH 010/265] refactor: do not drop/set index --- main/como/merge_xomics.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index 87183a44..3d2d0791 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -59,10 +59,7 @@ def from_string(cls, value: str) -> AdjustmentMethod: def _load_rnaseq_tests(filename, context_name, prep_method: RNAPrepMethod) -> tuple[str, pd.DataFrame]: - """Load rnaseq results. - - Returns a dictionary of test (context, context, cell, etc ) names and rnaseq expression data - """ + """Load rnaseq results.""" config = Config() def load_dummy_dict(): @@ -111,7 +108,6 @@ def _merge_logical_table(df: pd.DataFrame): """ # step 1: get all plural ENTREZ_GENE_IDs in the input table, extract unique IDs - df.reset_index(drop=False, inplace=True) df.dropna(axis=0, subset=["entrez_gene_id"], inplace=True) df["entrez_gene_id"] = df["entrez_gene_id"].astype(str).str.replace(" /// ", "//").astype(str) @@ -164,7 +160,6 @@ def _merge_logical_table(df: pd.DataFrame): for merged_entrez_id, entrez_dups_list in entrez_dups_dict.items(): df["entrez_gene_id"].replace(to_replace=entrez_dups_list, value=merged_entrez_id, inplace=True) - df.set_index("entrez_gene_id", inplace=True) df = df.fillna(-1).groupby(level=0).max() df.replace(-1, np.nan, inplace=True) From 653e001c24bc8b42cfba61052c7ef8a763f3db85 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 17 Dec 2024 15:17:21 -0600 Subject: [PATCH 011/265] refactor: use new one-context approach --- main/como/merge_xomics.py | 337 +++++++++++++++++++++----------------- 1 file changed, 184 insertions(+), 153 deletions(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index 3d2d0791..fcd35653 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -243,89 +243,36 @@ async def _get_transcriptmoic_details(merged_df: pd.DataFrame, taxon_id: int) -> async def _merge_xomics( context_name: str, - expression_requirement, - proteomics_file=None, - trnaseq_file=None, - mrnaseq_file=None, - scrnaseq_file=None, - no_hc=False, - no_na=False, + expression_requirement: int, + trna_boolean_matrix: pd.DataFrame | None, + mrna_boolean_matrix: pd.DataFrame | None, + scrna_boolean_matrix: pd.DataFrame | None, + proteomic_boolean_matrix: pd.DataFrame | None, + output_merged_filepath: Path, + output_gene_activity_filepath: Path, + output_transcriptomic_details_filepath: Path, + taxon_id: int, + force_activate_high_confidence: bool = True, + adjust_for_missing_sources: bool = False, ): - """Merge rnaseq and/or proteomics active genes. - - :param proteomics_file: filename of proteomics config file in /main/data/config_sheets/ - :param trnaseq_file: filename of Total RNA-seq config file in /main/data/config_sheets/ - :param mrnaseq_file: filename of mRNA-seq config file in /main/data/config_sheets/ - :param scrnaseq_file: filename of single-cell RNA-seq config file in /main/data/config_sheets/ - :param no_hc: True if not adjusting for NA values (happens when gene missing from data source) - :param no_na: filename of single-cell RNA-seq config file in /main/data/config_sheets/ - :param context_name: sheet name to use, should be context, context, cell type, etc - :param expression_requirement: integer, minimum number of provided sources with active gene for a it to be in model - :return: dictionary where keys are contexts, (tissue name, control type etc) and values are expression tables - """ - config = Config() - logger.info(f"Merging data for {context_name}") - # load data for each source if it exists. IF not load an empty dummy dataset - trnaseq = _load_rnaseq_tests(filename=trnaseq_file, context_name=context_name, prep_method=RNAPrepMethod.TOTAL) - mrnaseq = _load_rnaseq_tests(filename=mrnaseq_file, context_name=context_name, prep_method=RNAPrepMethod.MRNA) - scrnaseq = _load_rnaseq_tests(filename=scrnaseq_file, context_name=context_name, prep_method=RNAPrepMethod.SCRNA) - proteomics = proteomics_gen.load_proteomics_tests(filename=proteomics_file, context_name=context_name) - - expression_list = [] - high_confidence_list = [] - merge_data = None - - if trnaseq[0] != "dummy": - expression_list.append(_ExpressedHeaderNames.TRNASEQ) - high_confidence_list.append(_HighExpressionHeaderNames.TRNASEQ) - trnaseq_data = trnaseq[1].loc[:, ["expressed", "high"]] - trnaseq_data.rename( - columns={ - "expressed": _ExpressedHeaderNames.TRNASEQ, - "high": _HighExpressionHeaderNames.TRNASEQ, - }, - inplace=True, - ) - merge_data = trnaseq_data - - if mrnaseq[0] != "dummy": - expression_list.append(_ExpressedHeaderNames.MRNASEQ) - high_confidence_list.append(_HighExpressionHeaderNames.MRNASEQ) - mrnaseq_data = mrnaseq[1].loc[:, ["expressed", "high"]] - mrnaseq_data.rename( - columns={ - "expressed": _ExpressedHeaderNames.MRNASEQ, - "high": _HighExpressionHeaderNames.MRNASEQ, - }, - inplace=True, - ) - merge_data = mrnaseq_data if merge_data is None else merge_data.join(mrnaseq_data, how="outer") - - if scrnaseq[0] != "dummy": - expression_list.append(_ExpressedHeaderNames.SCRNASEQ) - high_confidence_list.append(_HighExpressionHeaderNames.SCRNASEQ) - scrnaseq_data = scrnaseq[1].loc[:, ["expressed", "high"]] - scrnaseq_data.rename( - columns={ - "expressed": _ExpressedHeaderNames.SCRNASEQ, - "high": _HighExpressionHeaderNames.SCRNASEQ, - }, - inplace=True, - ) - merge_data = scrnaseq_data if merge_data is None else merge_data.join(scrnaseq_data, how="outer") - - if proteomics[0] != "dummy": - expression_list.append(_ExpressedHeaderNames.PROTEOMICS) - high_confidence_list.append(_HighExpressionHeaderNames.PROTEOMICS) - prote_data = proteomics[1].loc[:, ["expressed", "high"]] - prote_data.rename( - columns={ - "expressed": _ExpressedHeaderNames.PROTEOMICS, - "high": _HighExpressionHeaderNames.PROTEOMICS, - }, - inplace=True, - ) - merge_data = prote_data if merge_data is None else merge_data.join(prote_data, how="outer") + expression_list: list[str] = [] + high_confidence_list: list[str] = [] + merge_data = pd.DataFrame() + + for matrix, expressed_sourcetype, high_expressed_sourcetype in ( + (trna_boolean_matrix, _ExpressedHeaderNames.TRNASEQ, _HighExpressionHeaderNames.TRNASEQ), + (mrna_boolean_matrix, _ExpressedHeaderNames.MRNASEQ, _HighExpressionHeaderNames.MRNASEQ), + (scrna_boolean_matrix, _ExpressedHeaderNames.SCRNASEQ, _HighExpressionHeaderNames.SCRNASEQ), + (proteomic_boolean_matrix, _ExpressedHeaderNames.PROTEOMICS, _HighExpressionHeaderNames.PROTEOMICS), + ): + if matrix is None: + continue + + matrix: pd.DataFrame # re-define type to assist in type hinting for IDEs + expression_list.append(expressed_sourcetype) + high_confidence_list.append(high_expressed_sourcetype) + matrix.rename(columns={"expressed": expressed_sourcetype, "high": high_expressed_sourcetype}, inplace=True) + merge_data = matrix if merge_data.empty else merge_data.merge(matrix, on="entrez_gene_id", how="outer") if merge_data.empty: logger.critical( @@ -338,46 +285,31 @@ async def _merge_xomics( merge_data["active"] = 0 merge_data["required"] = 0 - if no_na: # dont adjust for na values - merge_data.loc[:, "Required"] = merge_data[expression_list].apply( - lambda x: expression_requirement if (expression_requirement - (num_sources - x.count()) > 0) else 1, - axis=1, - ) - else: # subtract one from requirement per NA - merge_data.loc[:, "Required"] = merge_data[expression_list].apply( + if adjust_for_missing_sources: # Subtract 1 from requirement per missing source + merge_data.loc[:, "required"] = merge_data[expression_list].apply( lambda x: expression_requirement - (num_sources - x.count()) if (expression_requirement - (num_sources - x.count()) > 0) else 1, axis=1, ) + else: # Do not adjust for missing sources + merge_data.loc[:, "required"] = merge_data[expression_list].apply( + lambda x: expression_requirement if (expression_requirement - (num_sources - x.count()) > 0) else 1, axis=1 + ) - # count number of sources gene is active in. Set to active in final output if at least adjusted expression reqirmnt - - if not no_hc: # set genes that are high-confidence in at least one data source to active - merge_data.loc[merge_data[high_confidence_list].sum(axis=1) > 0, "Active"] = 1 - - # merge_data = merge_data.astype(int) - merge_data = merge_data - - filepath = config.result_dir / context_name / f"merged_{context_name}.csv" - merge_data.to_csv(filepath, index_label="entrez_gene_id") - - filepath = config.result_dir / context_name / f"ActiveGenes_{context_name}_Merged.csv" - merge_data.reset_index(drop=False, inplace=True) - - split_entrez = split_gene_expression_data(merge_data) - split_entrez.to_csv(filepath, index_label="entrez_gene_id") - files_dict = {context_name: filepath.as_posix()} + # Count the number of sources each gene is active in + # set to active in final output if we meet the adjusted expression requirement merge_data["total_expressed"] = merge_data[expression_list].sum(axis=1) merge_data.loc[merge_data["total_expressed"] >= merge_data["required"], "active"] = 1 - transcriptomic_details = await _get_transcriptmoic_details(merge_data) - transcriptomic_details_filepath = filepath.parent / f"TranscriptomicDetails_{context_name}.csv" - transcriptomic_details.to_csv(transcriptomic_details_filepath, index=False) + if force_activate_high_confidence: # If a gene is high-confidence in at least 1 data source, set it to active + merge_data.loc[merge_data[high_confidence_list].sum(axis=1) > 0, "active"] = 1 - logger.success(f"{context_name}: Save to {filepath}\n") + merge_data.to_csv(output_merged_filepath, index=False) + transcriptomic_details = await _get_transcriptmoic_details(merge_data, taxon_id=taxon_id) + transcriptomic_details.to_csv(output_transcriptomic_details_filepath, index=False) - return files_dict + return {context_name: output_gene_activity_filepath.as_posix()} async def _process( @@ -489,7 +421,7 @@ async def _process( ) adjusted_expression_requirement = 1 - await _new_merge_xomics( + await _merge_xomics( context_name=context_name, expression_requirement=adjusted_expression_requirement, trna_boolean_matrix=trna_boolean_matrix, @@ -505,67 +437,166 @@ async def _process( ) - - return - - -async def merge_xomics( - trnaseq_filepath: str | Path | None = None, - mrnaseq_filepath: str | Path | None = None, - scrnaseq_filepath: str | Path | None = None, - proteomics_filepath: str | Path | None = None, - trna_weight: float = 1, - mrna_weight: float = 1, - scrna_weight: float = 1, - proteomics_weight: float = 2, +async def merge_xomics( # noqa: C901 + context_name: str, + trna_matrix_or_filepath: Path | pd.DataFrame | None, + mrna_matrix_or_filepath: Path | pd.DataFrame | None, + scrna_matrix_or_filepath: Path | pd.DataFrame | None, + proteomic_matrix_or_filepath: Path | pd.DataFrame | None, + trna_boolean_matrix_or_filepath: Path | pd.DataFrame | None, + mrna_boolean_matrix_or_filepath: Path | pd.DataFrame | None, + scrna_boolean_matrix_or_filepath: Path | pd.DataFrame | None, + proteomic_boolean_matrix_or_filepath: Path | pd.DataFrame | None, + trna_batches: dict[int, list[str]], + mrna_batches: dict[int, list[str]], + scrna_batches: dict[int, list[str]], + proteomic_batches: dict[int, list[str]], + output_merge_activity_filepath: Path, + output_transcriptomic_details_filepath: Path, + output_trna_activity_filepath: Path | None, + output_mrna_activity_filepath: Path | None, + output_scrna_activity_filepath: Path | None, + output_proteomic_activity_filepath: Path | None, + output_final_model_scores_filepath: Path, + output_figure_dirpath: Path | None, + taxon_id: int, + trna_weight: int = 1, + mrna_weight: int = 1, + scrna_weight: int = 1, + proteomic_weight: int = 2, + minimum_source_expression: int = 1, expression_requirement: int | None = None, adjust_method: AdjustmentMethod = AdjustmentMethod.FLAT, - no_high_confidence: bool = False, - no_na: bool = False, + force_activate_high_confidence: bool = False, + adjust_for_na: bool = False, merge_zfpkm_distribution: bool = False, keep_transcriptomics_score: bool = True, + weighted_z_floor: int = -6, + weighted_z_ceiling: int = -6, ): """Merge expression tables of multiple sources (RNA-seq, proteomics) into one.""" + if expression_requirement < 1: + raise ValueError("Expression requirement must be at least 1!") + if expression_requirement is None: expression_requirement = sum( test is not None for test in [ - trnaseq_filepath, - mrnaseq_filepath, - scrnaseq_filepath, - proteomics_filepath, + trna_matrix_or_filepath, + mrna_matrix_or_filepath, + scrna_matrix_or_filepath, + proteomic_matrix_or_filepath, ] ) - elif expression_requirement < 1: - raise ValueError("Expression requirement must be at least 1!") - trnaseq_filepath = Path(trnaseq_filepath) if trnaseq_filepath else None - mrnaseq_filepath = Path(mrnaseq_filepath) if mrnaseq_filepath else None - scrnaseq_filepath = Path(scrnaseq_filepath) if scrnaseq_filepath else None - proteomics_filepath = Path(proteomics_filepath) if proteomics_filepath else None - - await _handle_context_batch( - trnaseq_filepath, - mrnaseq_filepath, - scrnaseq_filepath, - proteomics_filepath, - trna_weight, - mrna_weight, - scrna_weight, - proteomics_weight, - expression_requirement, - adjust_method, - no_high_confidence, - no_na, - merge_zfpkm_distribution, - keep_transcriptomics_score, + if all( + file is None + for file in [ + trna_matrix_or_filepath, + mrna_matrix_or_filepath, + scrna_matrix_or_filepath, + proteomic_matrix_or_filepath, + ] + ): + raise ValueError("No data was passed!") + + if adjust_method not in AdjustmentMethod: + raise ValueError(f"Adjustment method must be one of {AdjustmentMethod}; got: {adjust_method}") + + output_final_model_scores_filepath.parent.mkdir(parents=True, exist_ok=True) + if output_merge_activity_filepath: + output_merge_activity_filepath.parent.mkdir(parents=True, exist_ok=True) + if output_transcriptomic_details_filepath: + output_transcriptomic_details_filepath.parent.mkdir(parents=True, exist_ok=True) + if output_trna_activity_filepath: + output_trna_activity_filepath.parent.mkdir(parents=True, exist_ok=True) + if output_mrna_activity_filepath: + output_mrna_activity_filepath.parent.mkdir(parents=True, exist_ok=True) + if output_scrna_activity_filepath: + output_scrna_activity_filepath.parent.mkdir(parents=True, exist_ok=True) + if output_proteomic_activity_filepath: + output_proteomic_activity_filepath.parent.mkdir(parents=True, exist_ok=True) + if output_figure_dirpath: + output_figure_dirpath.mkdir(parents=True, exist_ok=True) + + # fmt: off + trna_matrix: pd.DataFrame | None = ( + pd.read_csv(trna_matrix_or_filepath) if isinstance(trna_matrix_or_filepath, Path) + else trna_matrix_or_filepath if isinstance(trna_matrix_or_filepath, pd.DataFrame) + else None ) + mrna_matrix: pd.DataFrame | None = ( + pd.read_csv(mrna_matrix_or_filepath) if isinstance(mrna_matrix_or_filepath, Path) + else mrna_matrix_or_filepath if isinstance(mrna_matrix_or_filepath, pd.DataFrame) + else None ) + scrna_matrix: pd.DataFrame | None = ( + pd.read_csv(scrna_matrix_or_filepath) if isinstance(scrna_matrix_or_filepath, Path) + else scrna_matrix_or_filepath if isinstance(scrna_matrix_or_filepath, pd.DataFrame) + else None ) + proteomic_matrix: pd.DataFrame | None = ( + pd.read_csv(proteomic_matrix_or_filepath) if isinstance(proteomic_matrix_or_filepath, Path) + else proteomic_matrix_or_filepath if isinstance(proteomic_matrix_or_filepath, pd.DataFrame) + else None ) + trna_boolean_matrix: pd.DataFrame | None = ( + pd.read_csv(trna_boolean_matrix_or_filepath) if isinstance(trna_boolean_matrix_or_filepath, Path) + else trna_boolean_matrix_or_filepath if isinstance(trna_boolean_matrix_or_filepath, pd.DataFrame) + else None ) + mrna_boolean_matrix: pd.DataFrame | None = ( + pd.read_csv(mrna_boolean_matrix_or_filepath) if isinstance(mrna_boolean_matrix_or_filepath, Path) + else mrna_boolean_matrix_or_filepath if isinstance(mrna_boolean_matrix_or_filepath, pd.DataFrame) + else None ) + scrna_boolean_matrix: pd.DataFrame | None = ( + pd.read_csv(scrna_boolean_matrix_or_filepath) if isinstance(scrna_boolean_matrix_or_filepath, Path) + else scrna_boolean_matrix_or_filepath if isinstance(scrna_boolean_matrix_or_filepath, pd.DataFrame) + else None ) + proteomic_boolean_matrix: pd.DataFrame | None = ( + pd.read_csv(proteomic_boolean_matrix_or_filepath) if isinstance(proteomic_boolean_matrix_or_filepath, Path) + else proteomic_boolean_matrix_or_filepath if isinstance(proteomic_boolean_matrix_or_filepath, pd.DataFrame) + else None ) + # fmt: on + + await _process( + context_name=context_name, + trna_matrix=trna_matrix, + mrna_matrix=mrna_matrix, + scrna_matrix=scrna_matrix, + proteomic_matrix=proteomic_matrix, + trna_boolean_matrix=trna_boolean_matrix, + mrna_boolean_matrix=mrna_boolean_matrix, + scrna_boolean_matrix=scrna_boolean_matrix, + proteomic_boolean_matrix=proteomic_boolean_matrix, + trna_batches=trna_batches, + mrna_batches=mrna_batches, + scrna_batches=scrna_batches, + proteomic_batches=proteomic_batches, + trna_weight=trna_weight, + mrna_weight=mrna_weight, + scrna_weight=scrna_weight, + proteomic_weight=proteomic_weight, + taxon_id=taxon_id, + minimum_source_expression=minimum_source_expression, + expression_requirement=expression_requirement, + weighted_z_floor=weighted_z_floor, + weighted_z_ceiling=weighted_z_ceiling, + adjust_method=adjust_method, + merge_zfpkm_distribution=merge_zfpkm_distribution, + keep_gene_score=keep_transcriptomics_score, + force_activate_high_confidence=force_activate_high_confidence, + adjust_for_missing_sources=adjust_for_na, + output_merge_activity_filepath=output_merge_activity_filepath, + output_transcriptomic_details_filepath=output_transcriptomic_details_filepath, + output_trna_activity_filepath=output_trna_activity_filepath, + output_mrna_activity_filepath=output_mrna_activity_filepath, + output_scrna_activity_filepath=output_scrna_activity_filepath, + output_proteomic_activity_filepath=output_proteomic_activity_filepath, + output_final_model_scores_filepath=output_final_model_scores_filepath, + output_figure_dirpath=output_figure_dirpath, ) From b5d89aa8ea3d2f393a06ad7f89b1049f720a097e Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 17 Dec 2024 15:17:52 -0600 Subject: [PATCH 012/265] refactor: import required modules --- main/como/combine_distributions.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index ed69413b..abcf95a9 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -1,10 +1,19 @@ +from __future__ import annotations + +from collections.abc import Iterator +from dataclasses import dataclass, fields from pathlib import Path +from typing import Literal, NamedTuple import numpy as np +import numpy.typing as npt import pandas as pd import plotly.express as px from loguru import logger +from como import graph +from como.utils import _num_rows + def _get_batch_name(x): return Path(x).stem From bb140ab1baed19c45fecacf4ce3357e7739a2b0e Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 17 Dec 2024 15:18:18 -0600 Subject: [PATCH 013/265] feat: create understandable dataclasses --- main/como/combine_distributions.py | 49 ++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index abcf95a9..f88a2076 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -15,6 +15,55 @@ from como.utils import _num_rows +class _IterableDataclass: + def __iter__(self) -> Iterator[str]: + return iter(getattr(self, field.name) for field in fields(self)) # type: ignore + + +class _BatchEntry(NamedTuple): + batch_num: int + sample_names: list[str] + + +@dataclass +class _InputMatrices(_IterableDataclass): + trna: Path | pd.DataFrame | None + mrna: Path | pd.DataFrame | None + scrna: Path | pd.DataFrame | None + proteomics: Path | pd.DataFrame | None + + +@dataclass +class _BatchNames(_IterableDataclass): + trna: list[_BatchEntry] + mrna: list[_BatchEntry] + scrna: list[_BatchEntry] + proteomics: list[_BatchEntry] + + +@dataclass +class _SourceWeights(_IterableDataclass): + trna: int + mrna: int + scrna: int + proteomics: int + + +@dataclass +class _OutputCombinedSourceFilepath(_IterableDataclass): + trna: Path | None + mrna: Path | None + scrna: Path | None + proteomics: Path | None + + +@dataclass +class _CombineOmicsInput: + z_score_matrix: pd.DataFrame + type: Literal["totalrna", "mrna", "scrna", "proteomics"] + weight: int + + def _get_batch_name(x): return Path(x).stem From 8102b0f2d65878ae32d8fb7096473f2080ab2e01 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 17 Dec 2024 15:22:39 -0600 Subject: [PATCH 014/265] refactor: remove unused modules --- main/como/combine_distributions.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index f88a2076..77513820 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -8,8 +8,6 @@ import numpy as np import numpy.typing as npt import pandas as pd -import plotly.express as px -from loguru import logger from como import graph from como.utils import _num_rows From d7caa252784734d48a394c747cd58626c52e2dc5 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 17 Dec 2024 15:23:41 -0600 Subject: [PATCH 015/265] refactor: remove multi-context-specific code --- main/como/combine_distributions.py | 83 ------------------------------ 1 file changed, 83 deletions(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index 77513820..78fd7ac3 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -62,89 +62,6 @@ class _CombineOmicsInput: weight: int -def _get_batch_name(x): - return Path(x).stem - - -def _parse_contexts_zfpkm(wd, contexts, prep): - batches = {} - for context in contexts: - files = (wd / context / prep).glob(f"rnaseq_{prep}_{context}.csv") - batches[context] = [_get_batch_name(f) for f in files] - return batches - - -def _parse_contexts_zumi(wd, contexts, prep): - batches = {} - for context in contexts: - files = (wd / context / prep).glob(f"*{prep}*.csv") - batches[context] = [_get_batch_name(f) for f in files] - return batches - - -def _parse_contexts_zscore_prot(wd, contexts): - batches = {} - for context in contexts: - files = (wd / context / "proteomics").glob("protein_zscore_Matrix_*.csv") - batches[context] = [_get_batch_name(f) for f in files] - return batches - - -def _merge_batch(wd, context, batch): - files = list(wd.glob(f"*{batch}*")) - nrep = [] - if not files: - raise ValueError(f"No files found for {context} - {batch}") - - for f in files: - zmat = pd.read_csv(f) - zmat.columns = pd.Index([c.lower() for c in zmat.columns]) - zmat["entrez_gene_id"] = zmat["entrez_gene_id"].astype(str).str.split("//").str[0] - - zmat = zmat.astype({col: float for col in zmat.columns if col != "entrez_gene_id"}) - zmat = zmat.astype({"entrez_gene_id": str}) - zmat = zmat.groupby("entrez_gene_id").max().reset_index() - zmat = zmat.dropna() - - nrep.append(zmat.shape[1] - 1) - entrez_gene = zmat["entrez_gene_id"] - rep_names = zmat.columns - zmat = pd.concat([zmat[col] for col in zmat.columns[1:]], axis=1) - zmat = pd.concat([entrez_gene, zmat], axis=1) - zmat = zmat.dropna() - zmat.columns = rep_names - - stack_df = pd.concat( - [ - pd.DataFrame( - {"entrez_gene_id": zmat["entrez_gene_id"], "zscore": zmat[col].astype(float), "source": col} - ) - for col in zmat.columns[1:] - ] - ) - - plot_name_png = wd / "figures" / f"plot_{context}_{Path(f).stem}.png" - - fig = px.histogram( - stack_df, - x="zscore", - color="source", - nbins=100, # Adjust as needed - marginal="rug", - title=f"Z-score Distribution for {context} - {Path(f).stem}", - ) - - fig.update_layout(xaxis_title="Z-score", yaxis_title="Frequency", font={"family": "sans-serif", "size": 12}) - - # Simplified plot for many sources (optional) - if len(stack_df["source"].unique()) > 10: - fig.update_layout(showlegend=False) - - plot_name_png.parent.mkdir(parents=True, exist_ok=True) - fig.write_image(plot_name_png) - - return zmat, nrep - def _combine_batch_zdistro(wd, context, batch, zmat): plot_name_png = wd / "figures" / f"plot_{context}_{batch}_combine_distro.png" From 672ae382e452e50d4e78e5e971dcf15e18f5ed3d Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 17 Dec 2024 15:24:13 -0600 Subject: [PATCH 016/265] feat: do not use hardcoded paths --- main/como/combine_distributions.py | 569 ++++++++++++----------------- 1 file changed, 231 insertions(+), 338 deletions(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index 78fd7ac3..0943b38c 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -62,375 +62,268 @@ class _CombineOmicsInput: weight: int - -def _combine_batch_zdistro(wd, context, batch, zmat): - plot_name_png = wd / "figures" / f"plot_{context}_{batch}_combine_distro.png" - - def weighted_z(x): - floor_score = -6 - ceil_score = 6 - x = np.array(x, dtype=float) +def _combine_batch_zdistro( + matrix: pd.DataFrame, + context_name: str, + batch_num: int, + output_png_filepath: Path, + weighted_z_floor: int = -6, + weighted_z_ceiling: int = 6, +) -> pd.DataFrame: + def weighted_z(x: npt.NDArray[float], floor: int, ceiling: int) -> npt.NDArray[float]: result = np.sum(x) / np.sqrt(len(x)) - return np.clip(result, floor_score, ceil_score) - - combine_z = zmat - if zmat.shape[1] > 2: - combine_z = np.apply_along_axis(weighted_z, axis=1, arr=zmat.iloc[:, 1:].values) - merge_df = pd.concat([zmat, pd.Series(combine_z, name="combined")], axis=1) - combine_z = pd.DataFrame({"entrez_gene_id": zmat["entrez_gene_id"].astype(str), "combine_z": combine_z}) - - stack_df = pd.concat( - [ - pd.DataFrame( - {"entrez_gene_id": merge_df["entrez_gene_id"], "zscore": merge_df[col].astype(float), "source": col} - ) - for col in merge_df.columns[1:] - ] - ) + return np.clip(result, floor, ceiling) - # Simplified plot for many sources (optional) - if len(stack_df["source"].unique()) > 10: - stack_df = stack_df[stack_df["source"] == "combined"] - - fig = px.histogram( - stack_df, - x="zscore", - color="source", - nbins=100, - marginal="rug", - title=f"Combined Z-score Distribution for {context} - {batch}", - ) - fig.update_layout(xaxis_title="Z-score", yaxis_title="Frequency", font={"family": "sans-serif", "size": 12}) - fig.write_image(plot_name_png) + if _num_rows(matrix) < 2: + return matrix + + weighted_matrix = np.apply_along_axis( + weighted_z, + axis=1, + arr=matrix.iloc[:, 1:].values, + floor=weighted_z_floor, + ceiling=weighted_z_ceiling, + ) + merge_df = pd.concat([matrix, pd.Series(weighted_matrix, name="combined")], axis=1) + weighted_matrix = pd.DataFrame( + { + "ensembl_gene_id": matrix["ensembl_gene_id"].astype(str), + "combine_z": weighted_matrix, + }, + ) - return combine_z + stack_df = pd.concat( + [ + pd.DataFrame( + {"ensembl_gene_id": merge_df["ensembl_gene_id"], "zscore": merge_df[col].astype(float), "source": col} + ) + for col in merge_df.columns[1:] + ] + ) + if len(stack_df["source"].unique()) > 10: + stack_df = stack_df[stack_df["source"] == "combined"] + graph.z_score_distribution( + stack_df, + title=f"Combined Z-score Distribution for {context_name} - batch #{batch_num}", + output_png_filepath=output_png_filepath, + ) + return weighted_matrix -def _combine_context_zdistro(wd, context, n_reps, zmat): - plot_name_png = wd / "figures" / f"plot_{context}_combine_batches_distro.png" - def weighted_z(x, n_reps): - floor_score = -6 - ceil_score = 6 - x = np.array(x, dtype=float) - nas = np.where(np.isnan(x))[0] - if len(nas) > 0: - x = np.delete(x, nas) - n_reps = np.delete(n_reps, nas) +def _combine_context_zdistro( + matrix: pd.DataFrame, + context_name: str, + batch_num: int, + num_replicates: int, + output_png_filepath: Path, + weighted_z_floor: int = -6, + weighted_z_ceiling: int = 6, +): + def weighted_z( + x: npt.NDArray[float], + n_reps: int, + floor: int, + ceiling: int, + ) -> npt.NDArray[float]: + na_values = np.where(np.isnan(x))[0] + if len(na_values) > 0: + x = np.delete(x, na_values) + n_reps = np.delete(n_reps, na_values) weights = n_reps / np.sum(n_reps) - numer = np.sum(weights * x) - denom = np.sqrt(np.sum(weights**2)) - result = numer / denom - return np.clip(result, floor_score, ceil_score) - - if zmat.shape[1] > 2: - combine_z = np.apply_along_axis(weighted_z, axis=1, arr=zmat.iloc[:, 1:].values, n_reps=n_reps) - merge_df = pd.concat([zmat, pd.Series(combine_z, name="combined")], axis=1) - combine_z = pd.DataFrame({"entrez_gene_id": zmat["entrez_gene_id"].astype(str), "combine_z": combine_z}) - - stack_df = pd.concat( - [ - pd.DataFrame( - {"entrez_gene_id": merge_df["entrez_gene_id"], "zscore": merge_df[col].astype(float), "source": col} - ) + numerator = np.sum(weights * x) + denominator = np.sqrt(np.sum(weights**2)) + result = numerator / denominator + return np.clip(result, floor, ceiling) + + if _num_rows(matrix) < 2: + matrix.columns = ["entrez_gene_id", "combine_z"] + return matrix + + weighted_matrix = np.apply_along_axis( + weighted_z, + axis=1, + arr=matrix.iloc[:, 1:].values, + n_reps=num_replicates, + floor=weighted_z_floor, + ceiling=weighted_z_ceiling, + ) + merge_df = pd.concat([matrix, pd.Series(weighted_matrix, name="combined")], axis=1) + weighted_matrix = pd.DataFrame( + {"ensembl_gene_id": matrix["ensembl_gene_id"].astype(str), "combine_z": weighted_matrix} + ) + stack_df = pd.concat( + [ + pd.DataFrame( + {"ensembl_gene_id": merge_df["ensembl_gene_id"], "zscore": merge_df[col].astype(float), "source": col} for col in merge_df.columns[1:] - ] - ) - - fig = px.histogram( - stack_df, - x="zscore", - color="source", - nbins=100, # Adjust as needed - marginal="rug", - title=f"Combined Batches Z-score Distribution for {context}", - ) - - fig.update_layout(xaxis_title="Z-score", yaxis_title="Frequency", font=dict(family="sans-serif", size=12)) # noqa: C408 - - fig.write_image(plot_name_png) - - else: - combine_z = zmat - combine_z.columns = ["entrez_gene_id", "combine_z"] - - return combine_z + ) + ] + ) + graph.z_score_distribution( + df=stack_df, + title=f"Combined Z-score Distribution for {context_name} - batch #{batch_num}", + output_png_filepath=output_png_filepath, + ) + return weighted_matrix def _combine_omics_zdistros( - wd, - context, - comb_batches_z_trna, - comb_batches_z_mrna, - comb_batches_z_scrna, - comb_batches_z_prot, - trna_weight: int, - mrna_weight: int, - scrna_weight: int, - proteomics_weight: int, - keep_gene_scores=True, + context: str, + zscore_results: list[_CombineOmicsInput], + output_png_filepath: Path, + weighted_z_floor: int = -6, + weighted_z_ceiling: int = 6, ): - fig_path = wd / context / "figures" - if not fig_path.exists(): - fig_path.mkdir(parents=True) - plot_name_png = fig_path / f"plot_{context}_combine_omics_distro.png" - - weights = [] - names = [] - dfs = [] - counter = 0 - if comb_batches_z_trna is not None: - counter += 1 - weights.append(trna_weight) - names.append("total") - dfs.append(comb_batches_z_trna) - if comb_batches_z_mrna is not None: - counter += 1 - weights.append(mrna_weight) - names.append("polyA") - dfs.append(comb_batches_z_mrna) - if comb_batches_z_scrna is not None: - counter += 1 - weights.append(scrna_weight) - names.append("singleCell") - dfs.append(comb_batches_z_scrna) - if comb_batches_z_prot is not None: - counter += 1 - weights.append(proteomics_weight) - names.append("proteome") - dfs.append(comb_batches_z_prot) - - def weighted_z(x, weights): - floor_score = -6 - ceil_score = 10 - x = np.array(x, dtype=float) - nas = np.where(np.isnan(x))[0] - if len(nas) > 0: - x = np.delete(x, nas) - weights = np.delete(weights, nas) + def weighted_z( + x: npt.NDArray[float], + weights, + floor: int, + ceiling: int, + ): + na_values = np.where(np.isnan(x))[0] + if len(na_values) > 0: + x = np.delete(x, na_values) + weights = np.delete(weights, na_values) weights = weights / np.sum(weights) - numer = np.sum(weights * x) - denom = np.sqrt(np.sum(weights**2)) - result = numer / denom - return np.clip(result, floor_score, ceil_score) - - zmat = dfs[0].copy() - zmat.columns = ["entrez_gene_id", names[0]] - for i in range(1, counter): - add_df = dfs[i] - add_df.columns = ["entrez_gene_id", names[i]] - zmat = pd.merge(zmat, add_df, on="entrez_gene_id", how="outer") - - if zmat.shape[1] > 2: - combine_z = np.apply_along_axis(weighted_z, axis=1, arr=zmat.iloc[:, 1:].values, weights=weights) - else: - combine_z = zmat.iloc[:, 1:].values - - combine_z = combine_z.ravel() - merge_df = pd.concat([zmat, pd.Series(combine_z, name="combined")], axis=1) - combine_z = pd.DataFrame({"entrez_gene_id": zmat["entrez_gene_id"].astype(str), "combine_z": combine_z}) + numerator = np.sum(weights * x) + denominator = np.sqrt(np.sum(weights**2)) + result = numerator / denominator + return np.clip(result, floor, ceiling) + + z_matrix = pd.DataFrame() + for result in zscore_results: + result.z_score_matrix.columns = ["ensembl_gene_id", result.type] + z_matrix = ( + result.z_score_matrix + if z_matrix.empty + else pd.merge(z_matrix, result.z_score_matrix, on="ensembl_gene_id", how="outer") + ) + + combined_z_matrix = ( + np.apply_along_axis( + weighted_z, + axis=1, + arr=z_matrix.iloc[:, 1:].values, + weights=[r.weight for r in zscore_results], + floor=weighted_z_floor, + ceiling=weighted_z_ceiling, + ) + if _num_rows(z_matrix) > 2 + else z_matrix.iloc[:, 1:].values + ).ravel() + merge_df = pd.concat([z_matrix, pd.Series(combined_z_matrix, name="combined")], axis=1) + combined_z_matrix = pd.DataFrame( + { + "ensembl_gene_id": z_matrix["ensembl_gene_id"].astype(str), + "combine_z": combined_z_matrix, + } + ) stack_df = pd.concat( [ pd.DataFrame( - {"entrez_gene_id": merge_df["entrez_gene_id"], "zscore": merge_df[col].astype(float), "source": col} + { + "ensembl_gene_id": merge_df["ensembl_gene_id"], + "zscore": merge_df[col].astype(float), + "source": col, + } ) for col in merge_df.columns[1:] ] ) - fig = px.histogram( - stack_df, - x="zscore", - color="source", - nbins=100, # Adjust as needed - marginal="rug", + graph.z_score_distribution( + df=stack_df, title=f"Combined Omics Z-score Distribution for {context}", + output_png_filepath=output_png_filepath, ) - - fig.update_layout(xaxis_title="Z-score", yaxis_title="Frequency", font={"family": "sans-serif", "size": 12}) - - fig.write_image(plot_name_png) - - return combine_z - - -def _combine_zscores( # noqa: C901 - working_dir, - context_names, - global_use_mrna, - global_use_trna, - global_use_scrna, - global_use_proteins, - keep_gene_scores, - global_trna_weight, - global_mrna_weight, - global_scrna_weight, - global_protein_weight, + return combined_z_matrix + + +def _combine_zscores( + context_name: str, + input_matrices: _InputMatrices, + batch_names: _BatchNames, + source_weights: _SourceWeights, + output_filepaths: _OutputCombinedSourceFilepath, + output_figure_dirpath: Path, + output_final_model_scores: Path, + weighted_z_floor: int = -6, + weighted_z_ceiling: int = 6, ): - working_dir = Path(working_dir) - figure_output_dir = working_dir / "figures" - figure_output_dir.mkdir(parents=True, exist_ok=True) - - global_trna_batches = _parse_contexts_zfpkm(working_dir, context_names, "total") - global_mrna_batches = _parse_contexts_zfpkm(working_dir, context_names, "mrna") - global_scrna_batches = _parse_contexts_zumi(working_dir, context_names, "scrna") - global_protein_batches = _parse_contexts_zscore_prot(working_dir, context_names) - - for context in context_names: - context_use_trna = global_use_trna - context_use_mrna = global_use_mrna - context_use_scrna = global_use_scrna - context_use_proteins = global_use_proteins - - context_trna_batch = global_trna_batches.get(context, []) - if len(context_trna_batch) == 0 and global_use_trna: - context_use_trna = False - logger.warning(f"No total RNA-seq zFPKM Matrix files found for {context}. Will not use for this context.") - - context_mrna_batch = global_mrna_batches.get(context, []) - if len(context_mrna_batch) == 0 and global_use_mrna: - context_use_mrna = False - logger.warning(f"No polyA RNA-seq zFPKM Matrix files found for {context}. Will not use for this context.") - - context_scrna_batch = global_scrna_batches.get(context, []) - if len(context_scrna_batch) == 0 and global_use_scrna: - context_use_scrna = False - logger.warning(f"No SC RNA-seq zFPKM Matrix files found for {context}. Will not use for this context.") - - context_protein_batch = global_protein_batches.get(context, []) - if len(context_protein_batch) == 0 and global_use_proteins: - context_use_proteins = False - logger.warning(f"No proteomics z-score Matrix files found for {context}. Will not use for this context.") - - comb_batches_z_trna = None - if context_use_trna: - logger.info("Will merge total RNA-seq distributions") - trna_workdir = working_dir / context / "total" - num_reps = [] - merge_z_data = pd.DataFrame() - - for batch in context_trna_batch: - res = _merge_batch(trna_workdir, context, batch) - z_matrix = res[0] - num_reps.extend(res[1]) - combine_z_matrix = _combine_batch_zdistro(trna_workdir, context, batch, z_matrix) - combine_z_matrix.columns = ["entrez_gene_id", batch] - merge_z_data = ( - combine_z_matrix - if merge_z_data.empty - else pd.merge(merge_z_data, combine_z_matrix, on="entrez_gene_id", how="outer") - ) - - comb_batches_z_trna = _combine_context_zdistro(trna_workdir, context, num_reps, merge_z_data) - filename = trna_workdir / f"combined_zFPKM_{context}.csv" - comb_batches_z_trna.to_csv(filename, index=False) - - if not context_use_proteins and not context_use_mrna and not context_use_scrna: - filename = trna_workdir / f"model_scores_{context}.csv" - comb_batches_z_trna.to_csv(filename, index=False) - - comb_batches_z_mrna = None - if context_use_mrna: - logger.info("Will merge polyA enriched RNA-seq distributions") - mrna_workdir = working_dir / context / "mrna" - num_reps = [] + output_figure_dirpath.mkdir(parents=True, exist_ok=True) + source_name: list[str] = ["totalrna", "mrna", "scrna", "proteomics"] + zscore_results: list[_CombineOmicsInput] = [] + for matrix, source in zip(input_matrices, source_name): + matrix: pd.DataFrame | None = pd.read_csv(matrix) if isinstance(matrix, Path) else matrix + + if matrix is not None: + if source == "totalrna": + batch_data = batch_names.trna + weight = source_weights.trna + output_filepath = output_filepaths.trna + elif source == "mrna": + batch_data = batch_names.mrna + weight = source_weights.mrna + output_filepath = output_filepaths.mrna + elif source == "scrna": + batch_data = batch_names.scrna + weight = source_weights.scrna + output_filepath = output_filepaths.scrna + elif source == "proteomics": + batch_data = batch_names.proteomics + weight = source_weights.proteomics + output_filepath = output_filepaths.proteomics + else: + raise ValueError(f"Invalid source; got '{source}', expected one of '{','.join(source_name)}'") + + replicate_count: list[int] = [] merge_z_data = pd.DataFrame() - for batch in context_mrna_batch: - res = _merge_batch(mrna_workdir, context, batch) - z_matrix = res[0] - num_reps.extend(res[1]) - combine_z_matrix = _combine_batch_zdistro(mrna_workdir, context, batch, z_matrix) - combine_z_matrix.columns = ["entrez_gene_id", batch] - merge_z_data = ( - combine_z_matrix - if merge_z_data.empty - else pd.merge(merge_z_data, combine_z_matrix, on="entrez_gene_id", how="outer") - ) - comb_batches_z_mrna = _combine_context_zdistro(mrna_workdir, context, num_reps, merge_z_data) - filename = mrna_workdir / f"combined_zFPKM_{context}.csv" - comb_batches_z_mrna.to_csv(filename, index=False) - - if not context_use_proteins and not context_use_trna and not context_use_scrna: - filename = mrna_workdir / f"model_scores_{context}.csv" - comb_batches_z_mrna.to_csv(filename, index=False) - - comb_batches_z_scrna = None - if context_use_scrna: - logger.info(f"Will merge single-cell RNA-seq distributions for {context}") - scrna_workdir = working_dir / context / "scrna" - num_reps = [] - merge_z_data = pd.DataFrame() - for batch in context_scrna_batch: - res = _merge_batch(scrna_workdir, context, batch) - z_matrix = res[0] - num_reps.extend(res[1]) - combine_z_matrix = _combine_batch_zdistro(scrna_workdir, context, batch, z_matrix) - combine_z_matrix.columns = ["entrez_gene_id", batch] - merge_z_data = ( - combine_z_matrix - if merge_z_data.empty - else pd.merge(merge_z_data, combine_z_matrix, on="entrez_gene_id", how="outer") + batch: _BatchEntry + for batch in batch_data: + replicate_count.append(len(batch.sample_names)) + + batch_df: pd.DataFrame = matrix[["ensembl_gene_id", *batch.sample_names]] + # graph.z_score_distribution( + # batch_df, + # title=f"Z-Score Distribution for {context_name} - batch #{batch.batch_num} - {source}", + # output_png_filepath=output_figure_dirpath + # / f"{source}_batch{batch.batch_num}_zscore_distribution.png", + # ) + combine_z_matrix: pd.DataFrame = _combine_batch_zdistro( + matrix=batch_df, + context_name=context_name, + batch_num=batch.batch_num, + output_png_filepath=( + output_figure_dirpath + / f"combined_{source}_{context_name}_batch{batch.batch_num}_distribution.png" + ), + weighted_z_floor=weighted_z_floor, + weighted_z_ceiling=weighted_z_ceiling, ) - - comb_batches_z_scrna = _combine_context_zdistro(scrna_workdir, context, num_reps, merge_z_data) - filename = scrna_workdir / f"combined_zFPKM_{context}.csv" - comb_batches_z_scrna.to_csv(filename, index=False) - - if not context_use_proteins and not context_use_trna and not context_use_mrna: - filename = scrna_workdir / f"model_scores_{context}.csv" - comb_batches_z_scrna.to_csv(filename, index=False) - - comb_batches_z_prot = None - if context_use_proteins: - logger.info("Will merge protein abundance distributions") - protein_workdir = working_dir / context / "proteomics" - num_reps = [] - merge_z_data = pd.DataFrame() - for batch in context_protein_batch: - res = _merge_batch(protein_workdir, context, batch) - z_matrix = res[0] - num_reps.extend(res[1]) - combine_z_matrix = _combine_batch_zdistro(protein_workdir, context, batch, z_matrix) - combine_z_matrix.columns = ["entrez_gene_id", batch] + combine_z_matrix.columns = ["ensembl_gene_id", batch.batch_num] merge_z_data = ( combine_z_matrix if merge_z_data.empty - else pd.merge(merge_z_data, combine_z_matrix, on="entrez_gene_id", how="outer") + else pd.merge(merge_z_data, combine_z_matrix, on="ensembl_gene_id", how="outer") ) - - comb_batches_z_prot = _combine_context_zdistro(protein_workdir, context, num_reps, merge_z_data) - filename = protein_workdir / f"combined_zscore_proteinAbundance_{context}.csv" - comb_batches_z_prot.to_csv(filename, index=False) - - if not context_use_mrna and not context_use_trna and not context_use_scrna: - filename = protein_workdir / f"model_scores_{context}.csv" - comb_batches_z_prot.to_csv(filename, index=False) - - if ( - comb_batches_z_mrna is None - and comb_batches_z_trna is None - and comb_batches_z_scrna is None - and comb_batches_z_prot is None - ): - logger.critical( - f"The context '{context}' was found in the configuration file but no data was found on disk!" + combine_batches_zscore = _combine_context_zdistro( + matrix=merge_z_data, + context_name=context_name, + batch_num=batch.batch_num, + num_replicates=sum(replicate_count), + output_png_filepath=output_figure_dirpath / f"totalrna_{context_name}_combined_distribution.png", + weighted_z_floor=weighted_z_floor, + weighted_z_ceiling=weighted_z_ceiling, ) - continue - - comb_omics_z = _combine_omics_zdistros( - wd=working_dir, - context=context, - comb_batches_z_trna=comb_batches_z_trna, - comb_batches_z_mrna=comb_batches_z_mrna, - comb_batches_z_scrna=comb_batches_z_scrna, - comb_batches_z_prot=comb_batches_z_prot, - trna_weight=global_trna_weight, - mrna_weight=global_mrna_weight, - scrna_weight=global_scrna_weight, - proteomics_weight=global_protein_weight, - ) + zscore_results.append(_CombineOmicsInput(z_score_matrix=combine_batches_zscore, type=source, weight=weight)) # type: ignore + combine_batches_zscore.to_csv(output_filepath, index=False) - filename = working_dir / context / f"model_scores_{context}.csv" - comb_omics_z.to_csv(filename, index=False) + combined_z_omics = _combine_omics_zdistros( + context=context_name, + zscore_results=zscore_results, + output_png_filepath=output_figure_dirpath / f"{context_name}_combined_omics_distribution.png", + ) + combined_z_omics.to_csv(output_final_model_scores, index=False) From f825055856b414570e8aa68769bf28f79a5cca75 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 17 Dec 2024 15:24:42 -0600 Subject: [PATCH 017/265] fix: do not overlap with built-in filenames --- main/como/{types.py => data_types.py} | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) rename main/como/{types.py => data_types.py} (75%) diff --git a/main/como/types.py b/main/como/data_types.py similarity index 75% rename from main/como/types.py rename to main/como/data_types.py index 916d3a25..a544aa8d 100644 --- a/main/como/types.py +++ b/main/como/data_types.py @@ -1,28 +1,9 @@ from __future__ import annotations -from abc import ABC from enum import Enum from pathlib import Path from typing import Literal -from pydantic import BaseModel, ConfigDict -from pydantic_settings import BaseSettings, SettingsConfigDict - - -class _BaseModel(BaseModel, ABC): - model_config = ConfigDict() - - -class _BaseArguments(BaseSettings, ABC): - model_config = SettingsConfigDict( - cli_parse_args=True, - cli_kebab_case=True, - nested_model_default_partial_update=True, - case_sensitive=True, - cli_avoid_json=True, - cli_enforce_required=True, - ) - class RNAPrepMethod(Enum): TOTAL = "total" @@ -71,5 +52,6 @@ def from_string(value: str) -> FilteringTechnique: raise ValueError(f"Got a filtering technique of '{value}'; should be one of: {possible_values}") -type_path = str | Path -type_rna = Literal["total", "mrna"] +PATH_TYPE = str | Path +RNA_TYPE = Literal["total", "mrna"] +LOG_LEVEL = Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] From 83525726305f0925e0f43e4c7a17cbf23436f7d0 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 17 Dec 2024 15:25:20 -0600 Subject: [PATCH 018/265] feat: numpy typing; count rows/columns function --- main/como/utils.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/main/como/utils.py b/main/como/utils.py index a359de0f..84097b8f 100644 --- a/main/como/utils.py +++ b/main/como/utils.py @@ -9,6 +9,7 @@ from typing import ClassVar import aiofiles +import numpy.typing as npt import pandas as pd from fast_bioservices import BioDBNet, Output, Taxon from fast_bioservices.pipeline import ( @@ -263,3 +264,11 @@ async def convert_gene_data(values: list[str], taxon_id: int | str | Taxon) -> p def _listify(value): """Convert items into a list.""" return [value] if not isinstance(value, list) else value + + +def _num_rows(item: pd.DataFrame | npt.NDArray) -> int: + return item.shape[1] + + +def _num_columns(item: pd.DataFrame | npt.NDArray) -> int: + return item.shape[0] From 75c9753b91a017162b34864ba0bc9defe339a8db Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 17 Dec 2024 15:25:31 -0600 Subject: [PATCH 019/265] fix: allow not setting index --- main/como/utils.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/main/como/utils.py b/main/como/utils.py index 84097b8f..74d924cf 100644 --- a/main/como/utils.py +++ b/main/como/utils.py @@ -144,11 +144,16 @@ def stringlist_to_list(stringlist: str | list[str]) -> list[str]: return new_list -def split_gene_expression_data(expression_data: pd.DataFrame, recon_algorithm: Algorithm | None = None): +def split_gene_expression_data( + expression_data: pd.DataFrame, + recon_algorithm: Algorithm | None = None, + entrez_as_index: bool = True, +): """Split the gene expression data into single-gene and multiple-gene names. :param expression_data: The gene expression data to map :param recon_algorithm: The recon algorithm used to generate the gene expression data + :param entrez_as_index: Should the 'entrez_gene_id' column be set as the index :return: """ expression_data.columns = [c.lower() for c in expression_data.columns] @@ -156,15 +161,15 @@ def split_gene_expression_data(expression_data: pd.DataFrame, recon_algorithm: A expression_data.rename(columns={"combine_z": "active"}, inplace=True) expression_data = expression_data[["entrez_gene_id", "active"]] - expression_data.loc[:, "entrez_gene_id"] = expression_data["entrez_gene_id"].astype(str) - single_gene_names = expression_data[~expression_data["entrez_gene_id"].str.contains("//")] - multiple_gene_names = expression_data[expression_data["entrez_gene_id"].str.contains("//")] + single_gene_names = expression_data[~expression_data["entrez_gene_id"].astype(str).str.contains("//")] + multiple_gene_names = expression_data[expression_data["entrez_gene_id"].astype(str).str.contains("//")] split_gene_names = multiple_gene_names.assign( entrez_gene_id=multiple_gene_names["entrez_gene_id"].str.split("///") ).explode("entrez_gene_id") gene_expressions = pd.concat([single_gene_names, split_gene_names], axis=0, ignore_index=True) - gene_expressions.set_index("entrez_gene_id", inplace=True) + if entrez_as_index: + gene_expressions.set_index("entrez_gene_id", inplace=True) return gene_expressions From 8600054e06dfbaf6ef73a3e7ab78f9bd750ecd80 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 17 Dec 2024 15:25:59 -0600 Subject: [PATCH 020/265] fix: use new data_types file --- main/como/rnaseq_preprocess.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index 83eb504f..5004ff28 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -18,7 +18,7 @@ from fast_bioservices.pipeline import ensembl_to_gene_id_and_symbol, gene_symbol_to_ensembl_and_gene_id from loguru import logger -from como.types import RNAPrepMethod, type_path, type_rna +from como.data_types import LOG_LEVEL, PATH_TYPE, RNA_TYPE, RNAPrepMethod from como.utils import _listify @@ -257,7 +257,7 @@ async def _write_counts_matrix( config_df: pd.DataFrame, como_context_dir: Path, output_counts_matrix_filepath: Path, - rna: type_rna, + rna: RNA_TYPE, ) -> pd.DataFrame: """Create a counts matrix file by reading gene counts table(s).""" study_metrics = _organize_gene_counts_files(data_dir=como_context_dir) @@ -508,9 +508,9 @@ async def read_counts(file: Path) -> list[str]: async def _create_matrix_file( context_name: str, output_config_filepath: Path, - como_context_dir: type_path, + como_context_dir: PATH_TYPE, output_counts_matrix_filepath: Path, - rna: type_rna, + rna: RNA_TYPE, ) -> None: config_df = await _create_config_df(context_name, como_context_dir=como_context_dir) await _write_counts_matrix( @@ -536,7 +536,7 @@ async def _process( output_mrna_matrix_filepath: Path | None, cache: bool, ): - rna_types: list[tuple[type_rna, Path, Path]] = [] + rna_types: list[tuple[RNA_TYPE, Path, Path]] = [] if output_trna_config_filepath: rna_types.append(("total", output_trna_config_filepath, output_trna_matrix_filepath)) if output_mrna_config_filepath: From e8086f86a64b3deeee2ba4ae6e4a3fb84e92ded1 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 17 Dec 2024 15:26:25 -0600 Subject: [PATCH 021/265] fix: function renaming; remove unused variables --- main/como/merge_xomics.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index fcd35653..f15654df 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -12,8 +12,8 @@ from como.combine_distributions import ( _BatchEntry, _BatchNames, + _combine_zscores, _InputMatrices, - _new_combine_zscores, _OutputCombinedSourceFilepath, _SourceWeights, ) @@ -338,7 +338,6 @@ async def _process( weighted_z_ceiling: int, adjust_method: AdjustmentMethod, merge_zfpkm_distribution: bool, - keep_gene_score: bool, force_activate_high_confidence: bool, adjust_for_missing_sources: bool, output_merge_activity_filepath: Path, @@ -354,7 +353,7 @@ async def _process( num_sources = sum(1 for source in [trna_matrix, mrna_matrix, scrna_matrix, proteomic_matrix] if source is not None) if merge_zfpkm_distribution: - _new_combine_zscores( + _combine_zscores( context_name=context_name, input_matrices=_InputMatrices( trna=trna_matrix, @@ -382,7 +381,6 @@ async def _process( ), output_figure_dirpath=output_figure_dirpath, output_final_model_scores=output_final_model_scores_filepath, - keep_gene_scores=keep_gene_score, weighted_z_floor=weighted_z_floor, weighted_z_ceiling=weighted_z_ceiling, ) @@ -470,7 +468,6 @@ async def merge_xomics( # noqa: C901 force_activate_high_confidence: bool = False, adjust_for_na: bool = False, merge_zfpkm_distribution: bool = False, - keep_transcriptomics_score: bool = True, weighted_z_floor: int = -6, weighted_z_ceiling: int = -6, ): @@ -588,7 +585,6 @@ async def merge_xomics( # noqa: C901 weighted_z_ceiling=weighted_z_ceiling, adjust_method=adjust_method, merge_zfpkm_distribution=merge_zfpkm_distribution, - keep_gene_score=keep_transcriptomics_score, force_activate_high_confidence=force_activate_high_confidence, adjust_for_missing_sources=adjust_for_na, output_merge_activity_filepath=output_merge_activity_filepath, From 3ca7ea4d070af6eb44dcbba182232acc7e06ddf0 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 17 Dec 2024 15:26:47 -0600 Subject: [PATCH 022/265] fix: do not require pydantic --- pyproject.toml | 2 -- uv.lock | 84 ++++++++++++++------------------------------------ 2 files changed, 23 insertions(+), 63 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index aa9fff60..ea9a3299 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,8 +17,6 @@ dependencies = [ "openpyxl>=3.1.5", "pandas>=1.3.5", "plotly>=5.24.1", - "pydantic-settings", - "pydantic>=2.10.3", "scanpy>=1.9.8", "scikit-learn>=1.5.2", "scipy>=1.7.3", diff --git a/uv.lock b/uv.lock index 3a417c7a..4ccb715f 100644 --- a/uv.lock +++ b/uv.lock @@ -335,7 +335,7 @@ wheels = [ [[package]] name = "cobamp" version = "0.2.2" -source = { git = "https://github.com/JoshLoecker/cobamp?rev=update_packages#bccb9141e0cb35081cdaa4a98b25bcdaf2aa442a" } +source = { git = "https://github.com/JoshLoecker/cobamp?rev=master#17bb8d8de6f7bdbdf5b2ff5b25da2b365a68f568" } dependencies = [ { name = "boolean-py" }, { name = "indexed" }, @@ -429,7 +429,7 @@ wheels = [ [[package]] name = "como" -version = "1.10.0" +version = "1.11.1" source = { editable = "." } dependencies = [ { name = "aiofiles" }, @@ -437,14 +437,11 @@ dependencies = [ { name = "cobamp" }, { name = "cobra" }, { name = "fast-bioservices" }, - { name = "gurobipy" }, { name = "kaleido" }, { name = "loguru" }, { name = "openpyxl" }, { name = "pandas" }, { name = "plotly" }, - { name = "pydantic" }, - { name = "pydantic-settings" }, { name = "scanpy" }, { name = "scikit-learn" }, { name = "scipy", version = "1.7.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, @@ -454,31 +451,34 @@ dependencies = [ ] [package.optional-dependencies] -interactive = [ - { name = "ipython" }, - { name = "jupyterlab" }, -] - -[package.dev-dependencies] dev = [ { name = "commitizen" }, { name = "commitlint" }, - { name = "cz-conventional-gitmoji" }, { name = "hypothesis" }, { name = "pytest" }, { name = "pytest-asyncio" }, { name = "pytest-cov" }, { name = "ruff" }, ] +gurobi = [ + { name = "gurobipy" }, +] +interactive = [ + { name = "ipython" }, + { name = "jupyterlab" }, +] [package.metadata] requires-dist = [ { name = "aiofiles", specifier = ">=24.1.0" }, { name = "aioftp", specifier = ">=0.23.1" }, - { name = "cobamp", git = "https://github.com/JoshLoecker/cobamp?rev=update_packages" }, + { name = "cobamp", git = "https://github.com/JoshLoecker/cobamp?rev=master" }, { name = "cobra", specifier = ">=0.28.0" }, + { name = "commitizen", marker = "extra == 'dev'", specifier = ">=4.1.0" }, + { name = "commitlint", marker = "extra == 'dev'", specifier = ">=1.3.0" }, { name = "fast-bioservices", specifier = ">=0.3.9" }, - { name = "gurobipy", specifier = ">=11.0" }, + { name = "gurobipy", marker = "extra == 'gurobi'", specifier = ">=10.0.0" }, + { name = "hypothesis", marker = "extra == 'dev'", specifier = ">=6.122.1" }, { name = "ipython", marker = "extra == 'interactive'", specifier = ">=8.0.0" }, { name = "jupyterlab", marker = "extra == 'interactive'", specifier = ">=4.3.2" }, { name = "kaleido", specifier = "==0.2.1" }, @@ -486,25 +486,15 @@ requires-dist = [ { name = "openpyxl", specifier = ">=3.1.5" }, { name = "pandas", specifier = ">=1.3.5" }, { name = "plotly", specifier = ">=5.24.1" }, - { name = "pydantic", specifier = ">=2.10.3" }, - { name = "pydantic-settings", git = "https://github.com/pydantic/pydantic-settings" }, + { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.3.3" }, + { name = "pytest-asyncio", marker = "extra == 'dev'", specifier = ">=0.24.0" }, + { name = "pytest-cov", marker = "extra == 'dev'", specifier = ">=6.0.0" }, + { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.8.0" }, { name = "scanpy", specifier = ">=1.9.8" }, { name = "scikit-learn", specifier = ">=1.5.2" }, { name = "scipy", specifier = ">=1.7.3" }, { name = "setuptools", specifier = "<60.0" }, - { name = "troppo", git = "https://github.com/JoshLoecker/troppo?rev=update_dependencies" }, -] - -[package.metadata.requires-dev] -dev = [ - { name = "commitizen", specifier = ">=4.1.0" }, - { name = "commitlint", specifier = ">=1.3.0" }, - { name = "cz-conventional-gitmoji", specifier = ">=0.6.1" }, - { name = "hypothesis", specifier = ">=6.122.1" }, - { name = "pytest", specifier = ">=8.3.3" }, - { name = "pytest-asyncio", specifier = ">=0.24.0" }, - { name = "pytest-cov", specifier = ">=6.0.0" }, - { name = "ruff", specifier = ">=0.8.0" }, + { name = "troppo", git = "https://github.com/JoshLoecker/troppo?rev=master" }, ] [[package]] @@ -602,19 +592,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321 }, ] -[[package]] -name = "cz-conventional-gitmoji" -version = "0.6.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "attrs" }, - { name = "commitizen" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/de/6e/0bd29b8df2fc2a1aca050bf92429b81b9dd91672dddf9d20e94008c80d99/cz_conventional_gitmoji-0.6.1.tar.gz", hash = "sha256:3fd4b355fa9a1ffc31192112f1807ab6c33203204c00f38a54c80643a2f407b8", size = 13755 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/fc/a3/2d9b33cb8b9898b0d3cc6147242ce9c3cee1e78739d793d1b197d8b573b8/cz_conventional_gitmoji-0.6.1-py3-none-any.whl", hash = "sha256:db8f51ea2f41389e6cc9986234524df6b4e1a3846ad738f5b946a811c3948623", size = 15151 }, -] - [[package]] name = "debugpy" version = "1.8.9" @@ -2080,15 +2057,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/33/72/f881b5e18fbb67cf2fb4ab253660de3c6899dbb2dba409d0b757e3559e3d/pydantic_core-2.27.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:981fb88516bd1ae8b0cbbd2034678a39dedc98752f264ac9bc5839d3923fa04c", size = 2001864 }, ] -[[package]] -name = "pydantic-settings" -version = "2.6.1" -source = { git = "https://github.com/pydantic/pydantic-settings#7bcb6edba2f683c83419283f977a7d16ec4c3b64" } -dependencies = [ - { name = "pydantic" }, - { name = "python-dotenv" }, -] - [[package]] name = "pygments" version = "2.18.0" @@ -2180,15 +2148,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 }, ] -[[package]] -name = "python-dotenv" -version = "1.0.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bc/57/e84d88dfe0aec03b7a2d4327012c1627ab5f03652216c63d49846d7a6c58/python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", size = 39115 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863 }, -] - [[package]] name = "python-json-logger" version = "2.0.7" @@ -2515,6 +2474,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7f/b7/20c6f3c0b656fe609675d69bc135c03aac9e3865912444be6339207b6648/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f66efbc1caa63c088dead1c4170d148eabc9b80d95fb75b6c92ac0aad2437d76", size = 686712 }, { url = "https://files.pythonhosted.org/packages/cd/11/d12dbf683471f888d354dac59593873c2b45feb193c5e3e0f2ebf85e68b9/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:22353049ba4181685023b25b5b51a574bce33e7f51c759371a7422dcae5402a6", size = 663936 }, { url = "https://files.pythonhosted.org/packages/72/14/4c268f5077db5c83f743ee1daeb236269fa8577133a5cfa49f8b382baf13/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:932205970b9f9991b34f55136be327501903f7c66830e9760a8ffb15b07f05cd", size = 696580 }, + { url = "https://files.pythonhosted.org/packages/30/fc/8cd12f189c6405a4c1cf37bd633aa740a9538c8e40497c231072d0fef5cf/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a52d48f4e7bf9005e8f0a89209bf9a73f7190ddf0489eee5eb51377385f59f2a", size = 663393 }, { url = "https://files.pythonhosted.org/packages/80/29/c0a017b704aaf3cbf704989785cd9c5d5b8ccec2dae6ac0c53833c84e677/ruamel.yaml.clib-0.2.12-cp310-cp310-win32.whl", hash = "sha256:3eac5a91891ceb88138c113f9db04f3cebdae277f5d44eaa3651a4f573e6a5da", size = 100326 }, { url = "https://files.pythonhosted.org/packages/3a/65/fa39d74db4e2d0cd252355732d966a460a41cd01c6353b820a0952432839/ruamel.yaml.clib-0.2.12-cp310-cp310-win_amd64.whl", hash = "sha256:ab007f2f5a87bd08ab1499bdf96f3d5c6ad4dcfa364884cb4549aa0154b13a28", size = 118079 }, { url = "https://files.pythonhosted.org/packages/fb/8f/683c6ad562f558cbc4f7c029abcd9599148c51c54b5ef0f24f2638da9fbb/ruamel.yaml.clib-0.2.12-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:4a6679521a58256a90b0d89e03992c15144c5f3858f40d7c18886023d7943db6", size = 132224 }, @@ -2523,6 +2483,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/86/29/88c2567bc893c84d88b4c48027367c3562ae69121d568e8a3f3a8d363f4d/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:811ea1594b8a0fb466172c384267a4e5e367298af6b228931f273b111f17ef52", size = 703012 }, { url = "https://files.pythonhosted.org/packages/11/46/879763c619b5470820f0cd6ca97d134771e502776bc2b844d2adb6e37753/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cf12567a7b565cbf65d438dec6cfbe2917d3c1bdddfce84a9930b7d35ea59642", size = 704352 }, { url = "https://files.pythonhosted.org/packages/02/80/ece7e6034256a4186bbe50dee28cd032d816974941a6abf6a9d65e4228a7/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7dd5adc8b930b12c8fc5b99e2d535a09889941aa0d0bd06f4749e9a9397c71d2", size = 737344 }, + { url = "https://files.pythonhosted.org/packages/f0/ca/e4106ac7e80efbabdf4bf91d3d32fc424e41418458251712f5672eada9ce/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1492a6051dab8d912fc2adeef0e8c72216b24d57bd896ea607cb90bb0c4981d3", size = 714498 }, { url = "https://files.pythonhosted.org/packages/67/58/b1f60a1d591b771298ffa0428237afb092c7f29ae23bad93420b1eb10703/ruamel.yaml.clib-0.2.12-cp311-cp311-win32.whl", hash = "sha256:bd0a08f0bab19093c54e18a14a10b4322e1eacc5217056f3c063bd2f59853ce4", size = 100205 }, { url = "https://files.pythonhosted.org/packages/b4/4f/b52f634c9548a9291a70dfce26ca7ebce388235c93588a1068028ea23fcc/ruamel.yaml.clib-0.2.12-cp311-cp311-win_amd64.whl", hash = "sha256:a274fb2cb086c7a3dea4322ec27f4cb5cc4b6298adb583ab0e211a4682f241eb", size = 118185 }, { url = "https://files.pythonhosted.org/packages/48/41/e7a405afbdc26af961678474a55373e1b323605a4f5e2ddd4a80ea80f628/ruamel.yaml.clib-0.2.12-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:20b0f8dc160ba83b6dcc0e256846e1a02d044e13f7ea74a3d1d56ede4e48c632", size = 133433 }, @@ -2531,6 +2492,7 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/52/a9/d39f3c5ada0a3bb2870d7db41901125dbe2434fa4f12ca8c5b83a42d7c53/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:749c16fcc4a2b09f28843cda5a193e0283e47454b63ec4b81eaa2242f50e4ccd", size = 706497 }, { url = "https://files.pythonhosted.org/packages/b0/fa/097e38135dadd9ac25aecf2a54be17ddf6e4c23e43d538492a90ab3d71c6/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bf165fef1f223beae7333275156ab2022cffe255dcc51c27f066b4370da81e31", size = 698042 }, { url = "https://files.pythonhosted.org/packages/ec/d5/a659ca6f503b9379b930f13bc6b130c9f176469b73b9834296822a83a132/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:32621c177bbf782ca5a18ba4d7af0f1082a3f6e517ac2a18b3974d4edf349680", size = 745831 }, + { url = "https://files.pythonhosted.org/packages/db/5d/36619b61ffa2429eeaefaab4f3374666adf36ad8ac6330d855848d7d36fd/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b82a7c94a498853aa0b272fd5bc67f29008da798d4f93a2f9f289feb8426a58d", size = 715692 }, { url = "https://files.pythonhosted.org/packages/b1/82/85cb92f15a4231c89b95dfe08b09eb6adca929ef7df7e17ab59902b6f589/ruamel.yaml.clib-0.2.12-cp312-cp312-win32.whl", hash = "sha256:e8c4ebfcfd57177b572e2040777b8abc537cdef58a2120e830124946aa9b42c5", size = 98777 }, { url = "https://files.pythonhosted.org/packages/d7/8f/c3654f6f1ddb75daf3922c3d8fc6005b1ab56671ad56ffb874d908bfa668/ruamel.yaml.clib-0.2.12-cp312-cp312-win_amd64.whl", hash = "sha256:0467c5965282c62203273b838ae77c0d29d7638c8a4e3a1c8bdd3602c10904e4", size = 115523 }, ] @@ -2962,7 +2924,7 @@ wheels = [ [[package]] name = "troppo" version = "0.1.0" -source = { git = "https://github.com/JoshLoecker/troppo?rev=update_dependencies#3b7302417d32e2fadaee356cc49e8c182a7dd531" } +source = { git = "https://github.com/JoshLoecker/troppo?rev=master#048edc8ebc8026aa7b04ef481b0637743f346d43" } dependencies = [ { name = "cobamp" }, { name = "cobra" }, From cb896b90f09a1253c9ce2e90c5975e9eefae64e0 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 17 Dec 2024 15:27:27 -0600 Subject: [PATCH 023/265] fix: use new file name --- main/como/rnaseq_gen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 7a9a5041..977a28a9 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -25,9 +25,9 @@ from scipy.signal import find_peaks from sklearn.neighbors import KernelDensity +from como.data_types import FilteringTechnique, RNAPrepMethod from como.migrations import gene_info_migrations from como.project import Config -from como.types import FilteringTechnique, RNAPrepMethod class _FilteringOptions(NamedTuple): From d620960106d93462e9e0e8a2d73b629bae6d252a Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 17 Dec 2024 15:29:12 -0600 Subject: [PATCH 024/265] fix: zfpkm should be performed on rows, not cols --- main/como/rnaseq_gen.py | 65 ++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 977a28a9..db3d50dd 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -272,7 +272,7 @@ def calculate_fpkm(metrics: NamedMetrics) -> NamedMetrics: return metrics -def _zfpkm_calculation(col: pd.Series, kernel: KernelDensity, peak_parameters: tuple[float, float]) -> _ZFPKMResult: +def _zfpkm_calculation(row: pd.Series, kernel: KernelDensity, peak_parameters: tuple[float, float]) -> _ZFPKMResult: """Log2 Transformations. Stabilize the variance in the data to make the distribution more symmetric; this is helpful for Gaussian fitting @@ -316,12 +316,12 @@ def _zfpkm_calculation(col: pd.Series, kernel: KernelDensity, peak_parameters: t a threshold for calling a gene as "expressed" : https://doi.org/10.1186/1471-2164-14-778 """ - col_log2: npt.NDArray = np.log2(col + 1) - col_log2 = np.nan_to_num(col_log2, nan=0) - refit: KernelDensity = kernel.fit(col_log2.reshape(-1, 1)) # type: ignore + row_log2: npt.NDArray = np.log2(row + 1) + row_log2 = np.nan_to_num(row_log2, nan=0) + refit: KernelDensity = kernel.fit(row_log2.reshape(-1, 1)) # type: ignore - # kde: KernelDensity = KernelDensity(kernel="gaussian", bandwidth=bandwidth).fit(col_log2.reshape(-1, 1)) - x_range = np.linspace(col_log2.min(), col_log2.max(), 1000) + # kde: KernelDensity = KernelDensity(kernel="gaussian", bandwidth=bandwidth).fit(row_log2.reshape(-1, 1)) + x_range = np.linspace(row_log2.min(), row_log2.max(), 1000) density = np.exp(refit.score_samples(x_range.reshape(-1, 1))) peaks, _ = find_peaks(density, height=peak_parameters[0], distance=peak_parameters[1]) peak_positions = x_range[peaks] @@ -333,9 +333,9 @@ def _zfpkm_calculation(col: pd.Series, kernel: KernelDensity, peak_parameters: t if len(peaks) != 0: mu = peak_positions.max() max_fpkm = density[peaks[np.argmax(peak_positions)]] - u = col_log2[col_log2 > mu].mean() + u = row_log2[row_log2 > mu].mean() stddev = (u - mu) * np.sqrt(np.pi / 2) - zfpkm = pd.Series((col_log2 - mu) / stddev, dtype=np.float32, name=col.name) + zfpkm = pd.Series((row_log2 - mu) / stddev, dtype=np.float32, name=row.name) return _ZFPKMResult(zfpkm=zfpkm, density=Density(x_range, density), mu=mu, std_dev=stddev, max_fpkm=max_fpkm) @@ -354,14 +354,13 @@ def zfpkm_transform( ) update_every_percent /= 100 - total = len(fpkm_df.columns) - update_per_step: int = int(np.ceil(total * update_every_percent)) - cores = min(multiprocessing.cpu_count() - 2, total) - logger.debug(f"Processing {total:,} samples through zFPKM transform using {cores} cores") + total_rows = len(fpkm_df) + update_per_step: int = int(np.ceil(total_rows * update_every_percent)) + cores = max(min(multiprocessing.cpu_count() - 2, total_rows), 1) # Get at least 1 core and at most cpu_count() - 2 logger.debug( - f"Will update every {update_per_step:,} steps as this is approximately " - f"{update_every_percent:.1%} of {total:,}" + f"zFPKM transforming {total_rows:,} gene(s) across {len(fpkm_df.columns)} sample(s) using {cores} cores" ) + logger.debug(f"Will update every {update_per_step:,} steps (~{update_every_percent:.1%} of {total_rows:,})") with Pool(processes=cores) as pool: kernel = KernelDensity(kernel="gaussian", bandwidth=bandwidth) @@ -369,34 +368,37 @@ def zfpkm_transform( partial_func = partial(_zfpkm_calculation, kernel=kernel, peak_parameters=peak_parameters) chunk_time = time.time() start_time = time.time() + log_padding = len(str(f"{total_rows:,}")) - log_padding = len(str(f"{total:,}")) - zfpkm_df = pd.DataFrame(data=0, index=fpkm_df.index, columns=fpkm_df.columns) + zfpkm_series: list[pd.Series | None] = [None] * total_rows results: dict[str, _ZFPKMResult] = {} result: _ZFPKMResult for i, result in enumerate( pool.imap( partial_func, - (fpkm_df[col] for col in fpkm_df.columns), + (row for _, row in fpkm_df.iterrows()), chunksize=chunksize, ) ): key = str(result.zfpkm.name) results[key] = result - zfpkm_df[key] = result.zfpkm + zfpkm_series[i] = result.zfpkm # show updates every X% and at the end, but skip on first iteration - if i != 0 and (i % update_per_step == 0 or i == total): + if i != 0 and (i % update_per_step == 0 or i >= total_rows): current_time = time.time() chunk = current_time - chunk_time total_time = current_time - start_time - formatted = f"{i:,}" + chunk_num = f"{i:,}" logger.debug( - f"Processed {formatted:>{log_padding}} of {total:,} - " + f"Processed {chunk_num:>{log_padding}} of {total_rows:,} - " f"chunk took {chunk:.1f} seconds - " f"running for {total_time:.1f} seconds" ) chunk_time = current_time + + zfpkm_df = pd.concat(zfpkm_series, axis=1) + return results, zfpkm_df @@ -408,7 +410,7 @@ def zfpkm_plot(results, *, plot_xfloor: int = -4, subplot_titles: bool = True): :param plot_xfloor: Lower limit for the x-axis. :param subplot_titles: Whether to display facet titles (sample names). """ - mega_df = pd.DataFrame(columns=["sample_name", "log2fpkm", "fpkm_density", "fitted_density_scaled"]) + to_concat: list[pd.DataFrame | None] = [None] * len(results) for name, result in results.items(): stddev = result.std_dev x = np.array(result.density.x) @@ -419,15 +421,18 @@ def zfpkm_plot(results, *, plot_xfloor: int = -4, subplot_titles: bool = True): max_fitted = fitted.max() scale_fitted = fitted * (max_fpkm / max_fitted) - df = pd.DataFrame( - { - "sample_name": [name] * len(x), - "log2fpkm": x, - "fpkm_density": y, - "fitted_density_scaled": scale_fitted, - } + to_concat.append( + pd.DataFrame( + { + "sample_name": [name] * len(x), + "log2fpkm": x, + "fpkm_density": y, + "fitted_density_scaled": scale_fitted, + } + ) ) - mega_df = pd.concat([mega_df, df], ignore_index=True) + mega_df = pd.concat(to_concat, ignore_index=True) + mega_df.columns = pd.Series(data=["sample_name", "log2fpkm", "fpkm_density", "fitted_density_scaled"]) mega_df = mega_df.melt(id_vars=["log2fpkm", "sample_name"], var_name="source", value_name="density") subplot_titles = list(results.keys()) if subplot_titles else None From 9541824388ac63022f4b8f558de3a715a6c3e157 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 17 Dec 2024 15:30:18 -0600 Subject: [PATCH 025/265] style: reorganize code --- main/como/rnaseq_gen.py | 72 +++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index db3d50dd..79c1984b 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -171,8 +171,10 @@ async def _build_matrix_results( :param taxon: The NCBI Taxon ID :return: A dataclass `ReadMatrixResults` """ - gene_info = gene_info_migrations(gene_info) conversion = await ensembl_to_gene_id_and_symbol(ids=matrix["ensembl_gene_id"].tolist(), taxon=taxon) + conversion["ensembl_gene_id"] = conversion["ensembl_gene_id"].str.split(",") + conversion = conversion.explode("ensembl_gene_id") + conversion.reset_index(inplace=True, drop=True) matrix = matrix.merge(conversion, on="ensembl_gene_id", how="left") # Only include Entrez and Ensembl Gene IDs that are present in `gene_info` @@ -181,6 +183,7 @@ async def _build_matrix_results( matrix = matrix.replace(to_replace="-", value=pd.NA).dropna() matrix["entrez_gene_id"] = matrix["entrez_gene_id"].astype(int) + gene_info = gene_info_migrations(gene_info) gene_info = gene_info.replace(to_replace="-", value=pd.NA).dropna() gene_info["entrez_gene_id"] = gene_info["entrez_gene_id"].astype(int) @@ -189,6 +192,7 @@ async def _build_matrix_results( on=["entrez_gene_id", "ensembl_gene_id"], how="inner", ) + gene_info = gene_info.merge( counts_matrix[["entrez_gene_id", "ensembl_gene_id"]], on=["entrez_gene_id", "ensembl_gene_id"], @@ -552,7 +556,7 @@ def tpm_quantile_filter(*, metrics: NamedMetrics, filtering_options: _FilteringO # Only keep `entrez_gene_ids` that pass `min_genes` metric.entrez_gene_ids = [gene for gene, keep in zip(entrez_ids, min_genes) if keep] - metric.gene_sizes = [gene for gene, keep in zip(gene_size, min_genes) if keep] + metric.gene_sizes = np.array(gene for gene, keep in zip(gene_size, min_genes) if keep) metric.count_matrix = metric.count_matrix.iloc[min_genes, :] metric.normalization_matrix = metrics[sample].normalization_matrix.iloc[min_genes, :] @@ -569,15 +573,13 @@ def zfpkm_filter(*, metrics: NamedMetrics, filtering_options: _FilteringOptions, min_sample_expression = filtering_options.replicate_ratio high_confidence_sample_expression = filtering_options.high_replicate_ratio cut_off = filtering_options.cut_off - - if calcualte_fpkm: - metrics = calculate_fpkm(metrics) + metrics = calculate_fpkm(metrics) if calcualte_fpkm else metrics metric: _StudyMetrics for metric in metrics.values(): # if fpkm was not calculated, the normalization matrix will be empty; collect the count matrix instead matrix = metric.count_matrix if metric.normalization_matrix.empty else metric.normalization_matrix - matrix = matrix[matrix.sum(axis=1) > 0] + matrix = matrix[matrix.sum(axis=1) > 0] # remove rows (genes) that have no counts minimums = matrix == 0 results, zfpkm_df = zfpkm_transform(matrix) @@ -628,7 +630,6 @@ async def _save_rnaseq_tests( rnaseq_matrix: pd.DataFrame, metadata_df: pd.DataFrame, gene_info_df: pd.DataFrame, - output_filepath: Path, prep: RNAPrepMethod, taxon: int, replicate_ratio: float, @@ -637,6 +638,8 @@ async def _save_rnaseq_tests( high_batch_ratio: float, technique: FilteringTechnique, cut_off: int | float, + output_boolean_activity_filepath: Path, + output_zscore_normalization_filepath: Path, ): """Save the results of the RNA-Seq tests to a CSV file.""" filtering_options = _FilteringOptions( @@ -656,7 +659,7 @@ async def _save_rnaseq_tests( metrics = read_counts_results.metrics entrez_gene_ids = read_counts_results.entrez_gene_ids - metrics = filter_counts( + metrics: NamedMetrics = filter_counts( context_name=context_name, metrics=metrics, technique=technique, @@ -664,11 +667,24 @@ async def _save_rnaseq_tests( prep=prep, ) + merged_zscore_df = pd.DataFrame() expressed_genes: list[str] = [] top_genes: list[str] = [] for metric in metrics.values(): expressed_genes.extend(metric.entrez_gene_ids) top_genes.extend(metric.high_confidence_entrez_gene_ids) + if metric.normalization_matrix is not None: + merged_zscore_df = ( + metric.normalization_matrix + if merged_zscore_df.empty + else pd.concat( + [merged_zscore_df, metric.normalization_matrix], + axis=1, + ) + ) + merged_zscore_df.index = pd.Series(entrez_gene_ids, name="entrez_gene_id") + merged_zscore_df.to_csv(output_zscore_normalization_filepath, index=True) + logger.success(f"Wrote z-score normalization matrix to {output_zscore_normalization_filepath}") expression_frequency = pd.Series(expressed_genes).value_counts() expression_df = pd.DataFrame( @@ -692,11 +708,11 @@ async def _save_rnaseq_tests( expressed_count = len(boolean_matrix[boolean_matrix["expressed"] == 1]) high_confidence_count = len(boolean_matrix[boolean_matrix["high"] == 1]) - boolean_matrix.to_csv(output_filepath, index=False) + boolean_matrix.to_csv(output_boolean_activity_filepath, index=False) logger.info( f"{context_name} - Found {expressed_count} expressed and {high_confidence_count} confidently expressed genes" ) - logger.success(f"Wrote boolean matrix to {output_filepath}") + logger.success(f"Wrote boolean matrix to {output_boolean_activity_filepath}") async def _create_metadata_df(path: Path) -> pd.DataFrame: @@ -708,15 +724,15 @@ async def _create_metadata_df(path: Path) -> pd.DataFrame: return pd.read_excel(path) -async def rnaseq_gen( # noqa: C901, allow complex function +async def rnaseq_gen( context_name: str, input_rnaseq_filepath: Path, input_gene_info_filepath: Path, - output_rnaseq_filepath: Path, prep: RNAPrepMethod, - taxon: int, - input_metadata_filepath: Path | None = None, - input_metadata_df: pd.DataFrame | None = None, + taxon_id: int, + output_boolean_activity_filepath: Path, + output_zscore_normalization_filepath: Path, + input_metadata_filepath_or_df: Path | pd.DataFrame, replicate_ratio: float = 0.5, high_replicate_ratio: float = 1.0, batch_ratio: float = 0.5, @@ -733,11 +749,11 @@ async def rnaseq_gen( # noqa: C901, allow complex function :param context_name: The name of the context being processed :param input_rnaseq_filepath: The filepath to the gene count matrix :param input_gene_info_filepath: The filepath to the gene info file - :param output_rnaseq_filepath: The filepath to write the output gene count matrix + :param output_boolean_activity_filepath: The filepath to write the output gene count matrix + :param output_zscore_normalization_filepath: The filepath to write the output z-score normalization matrix :param prep: The preparation method - :param taxon: The NCBI Taxon ID - :param input_metadata_filepath: The filepath to the metadata file - :param input_metadata_df: The metadata dataframe + :param taxon_id: The NCBI Taxon ID + :param input_metadata_filepath_or_df: The filepath or dataframe containing metadata information :param replicate_ratio: The percentage of replicates that a gene must appear in for a gene to be marked as "active" in a batch/study :param batch_ratio: The percentage of batches that a gene must appear in for a gene to be marked as 'active" @@ -749,9 +765,6 @@ async def rnaseq_gen( # noqa: C901, allow complex function :param cutoff: The cutoff value to use for the provided filtering technique :return: None """ - if not input_metadata_df and not input_metadata_filepath: - raise ValueError("At least one of input_metadata_filepath or input_metadata_df must be provided") - technique = ( FilteringTechnique.from_string(str(technique.lower())) if isinstance(technique, (str, int)) else technique ) @@ -787,20 +800,25 @@ async def rnaseq_gen( # noqa: C901, allow complex function ) logger.debug(f"Starting '{context_name}'") - output_rnaseq_filepath.parent.mkdir(parents=True, exist_ok=True) - + output_boolean_activity_filepath.parent.mkdir(parents=True, exist_ok=True) + metadata_df = ( + input_metadata_filepath_or_df + if isinstance(input_metadata_filepath_or_df, pd.DataFrame) + else await _create_metadata_df(input_metadata_filepath_or_df) + ) await _save_rnaseq_tests( context_name=context_name, rnaseq_matrix=await _read_counts(input_rnaseq_filepath), - metadata_df=input_metadata_df or await _create_metadata_df(input_metadata_filepath), + metadata_df=metadata_df, gene_info_df=pd.read_csv(input_gene_info_filepath), - output_filepath=output_rnaseq_filepath, prep=prep, - taxon=taxon, + taxon=taxon_id, replicate_ratio=replicate_ratio, batch_ratio=batch_ratio, high_replicate_ratio=high_replicate_ratio, high_batch_ratio=high_batch_ratio, technique=technique, cut_off=cutoff, + output_boolean_activity_filepath=output_boolean_activity_filepath, + output_zscore_normalization_filepath=output_zscore_normalization_filepath, ) From 4ba45e0b9ec530c4d86f110aac7c114bc4a0e4bf Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 17 Dec 2024 15:30:36 -0600 Subject: [PATCH 026/265] style: rename arguments --- main/como/rnaseq_preprocess.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index 5004ff28..b869a97e 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -578,12 +578,12 @@ async def rnaseq_preprocess( output_gene_info_filepath: Path, como_context_dir: Path | None = None, input_matrix_filepath: Path | list[Path] | None = None, - output_trna_config_filepath: Path | None = None, - output_mrna_config_filepath: Path | None = None, + output_trna_metadata_filepath: Path | None = None, + output_mrna_metadata_filepath: Path | None = None, output_trna_count_matrix_filepath: Path | None = None, output_mrna_count_matrix_filepath: Path | None = None, cache: bool = True, - log_level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] = "INFO", + log_level: LOG_LEVEL = "INFO", log_location: str | TextIOWrapper = sys.stderr, ) -> None: """Preprocesses RNA-seq data for downstream analysis. @@ -594,8 +594,8 @@ async def rnaseq_preprocess( :param context_name: The context/cell type being processed :param taxon: The NCBI taxonomy ID :param output_gene_info_filepath: Path to the output gene information CSV file - :param output_trna_config_filepath: Path to the output tRNA config file (if in "create" mode) - :param output_mrna_config_filepath: Path to the output mRNA config file (if in "create" mode) + :param output_trna_metadata_filepath: Path to the output tRNA config file (if in "create" mode) + :param output_mrna_metadata_filepath: Path to the output mRNA config file (if in "create" mode) :param output_trna_count_matrix_filepath: The path to write total RNA count matrices :param output_mrna_count_matrix_filepath: The path to write messenger RNA count matrices :param como_context_dir: If in "create" mode, the input path(s) to the COMO_input directory of the current context @@ -616,11 +616,11 @@ async def rnaseq_preprocess( output_gene_info_filepath = output_gene_info_filepath.resolve() como_context_dir = como_context_dir.resolve() input_matrix_filepath = [i.resolve() for i in _listify(input_matrix_filepath)] if input_matrix_filepath else None - output_trna_config_filepath = ( - output_trna_config_filepath.resolve() if output_trna_config_filepath else output_trna_config_filepath + output_trna_metadata_filepath = ( + output_trna_metadata_filepath.resolve() if output_trna_metadata_filepath else output_trna_metadata_filepath ) - output_mrna_config_filepath = ( - output_mrna_config_filepath.resolve() if output_mrna_config_filepath else output_mrna_config_filepath + output_mrna_metadata_filepath = ( + output_mrna_metadata_filepath.resolve() if output_mrna_metadata_filepath else output_mrna_metadata_filepath ) output_trna_count_matrix_filepath = ( output_trna_count_matrix_filepath.resolve() @@ -640,8 +640,8 @@ async def rnaseq_preprocess( como_context_dir=como_context_dir, input_matrix_filepath=input_matrix_filepath, output_gene_info_filepath=output_gene_info_filepath, - output_trna_config_filepath=output_trna_config_filepath, - output_mrna_config_filepath=output_mrna_config_filepath, + output_trna_config_filepath=output_trna_metadata_filepath, + output_mrna_config_filepath=output_mrna_metadata_filepath, output_trna_matrix_filepath=output_trna_count_matrix_filepath, output_mrna_matrix_filepath=output_mrna_count_matrix_filepath, cache=cache, From 0a0824e850480cbb89d72ad7d5ea05bb17c6b2a3 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 17 Dec 2024 15:36:59 -0600 Subject: [PATCH 027/265] fix: ignore mismatched types Signed-off-by: Josh Loecker --- main/como/rnaseq_gen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 79c1984b..1b9399b0 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -414,7 +414,7 @@ def zfpkm_plot(results, *, plot_xfloor: int = -4, subplot_titles: bool = True): :param plot_xfloor: Lower limit for the x-axis. :param subplot_titles: Whether to display facet titles (sample names). """ - to_concat: list[pd.DataFrame | None] = [None] * len(results) + to_concat: list[pd.DataFrame] = [None] * len(results) # type: ignore # ignoring because None is not of type pd.DataFrame for name, result in results.items(): stddev = result.std_dev x = np.array(result.density.x) From 2dbebb622c280c361cc1517b0434f839dfa8f690 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 17 Dec 2024 15:38:05 -0600 Subject: [PATCH 028/265] fix: misspelling Signed-off-by: Josh Loecker --- main/como/rnaseq_gen.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 1b9399b0..b8a2f735 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -239,7 +239,7 @@ def calculate_tpm(metrics: NamedMetrics) -> NamedMetrics: return metrics -def calculate_fpkm(metrics: NamedMetrics) -> NamedMetrics: +def _calculate_fpkm(metrics: NamedMetrics) -> NamedMetrics: """Calculate the Fragments Per Kilobase of transcript per Million mapped reads (FPKM) for each sample in the metrics dictionary.""" # noqa: E501 for study in metrics: matrix_values = [] @@ -568,12 +568,12 @@ def tpm_quantile_filter(*, metrics: NamedMetrics, filtering_options: _FilteringO return metrics -def zfpkm_filter(*, metrics: NamedMetrics, filtering_options: _FilteringOptions, calcualte_fpkm: bool) -> NamedMetrics: +def zfpkm_filter(*, metrics: NamedMetrics, filtering_options: _FilteringOptions, calculate_fpkm: bool) -> NamedMetrics: """Apply zFPKM filtering to the FPKM matrix for a given sample.""" min_sample_expression = filtering_options.replicate_ratio high_confidence_sample_expression = filtering_options.high_replicate_ratio cut_off = filtering_options.cut_off - metrics = calculate_fpkm(metrics) if calcualte_fpkm else metrics + metrics = _calculate_fpkm(metrics) if calculate_fpkm else metrics metric: _StudyMetrics for metric in metrics.values(): @@ -618,9 +618,9 @@ def filter_counts( case FilteringTechnique.tpm: return tpm_quantile_filter(metrics=metrics, filtering_options=filtering_options) case FilteringTechnique.zfpkm: - return zfpkm_filter(metrics=metrics, filtering_options=filtering_options, calcualte_fpkm=True) + return zfpkm_filter(metrics=metrics, filtering_options=filtering_options, calculate_fpkm=True) case FilteringTechnique.umi: - return zfpkm_filter(metrics=metrics, filtering_options=filtering_options, calcualte_fpkm=False) + return zfpkm_filter(metrics=metrics, filtering_options=filtering_options, calculate_fpkm=False) case _: raise ValueError(f"Technique must be one of {FilteringTechnique}") From cf06da4379097445fde06c216ee98e5c01db4d5e Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Wed, 25 Dec 2024 17:09:49 -0600 Subject: [PATCH 029/265] feat: move zscore graphing to its own module Signed-off-by: Josh Loecker --- main/como/graph/__init__.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 main/como/graph/__init__.py diff --git a/main/como/graph/__init__.py b/main/como/graph/__init__.py new file mode 100644 index 00000000..1bb4cdb8 --- /dev/null +++ b/main/como/graph/__init__.py @@ -0,0 +1,35 @@ +from pathlib import Path +from loguru import logger +import pandas as pd +import plotly.express as px + +__all__ = ["z_score_distribution"] + + +def z_score_distribution( + df: pd.DataFrame, + title: str, + output_png_filepath: Path, +): + if not output_png_filepath.suffix == ".png": + logger.warning( + f"Expected .png suffix for output_png_filepath, got {output_png_filepath.suffix}. Defaulting to .png" + ) + output_png_filepath = output_png_filepath.with_suffix(".png") + + fig = px.histogram( + df, + x="zscore", + color="source", + nbins=100, + marginal="rug", + title=title, + ) + + fig.update_layout(xaxis_title="Z-score", yaxis_title="Frequency", font={"family": "sans-serif", "size": 12}) + + # Simplified plot for many sources (optional) + if len(df["source"].unique()) > 10: + fig.update_layout(showlegend=False) + + fig.write_image(output_png_filepath) From e14af0c7901a7db21458b3b27e5762fd6b380f29 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Wed, 25 Dec 2024 17:09:59 -0600 Subject: [PATCH 030/265] fix: explicit import graphing Signed-off-by: Josh Loecker --- main/como/combine_distributions.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index 0943b38c..595f4442 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -9,7 +9,7 @@ import numpy.typing as npt import pandas as pd -from como import graph +from como.graph import z_score_distribution as graph_zscore_distribution from como.utils import _num_rows @@ -103,7 +103,7 @@ def weighted_z(x: npt.NDArray[float], floor: int, ceiling: int) -> npt.NDArray[f if len(stack_df["source"].unique()) > 10: stack_df = stack_df[stack_df["source"] == "combined"] - graph.z_score_distribution( + graph_zscore_distribution( stack_df, title=f"Combined Z-score Distribution for {context_name} - batch #{batch_num}", output_png_filepath=output_png_filepath, @@ -160,7 +160,7 @@ def weighted_z( ) ] ) - graph.z_score_distribution( + graph_zscore_distribution( df=stack_df, title=f"Combined Z-score Distribution for {context_name} - batch #{batch_num}", output_png_filepath=output_png_filepath, @@ -233,7 +233,7 @@ def weighted_z( ] ) - graph.z_score_distribution( + graph_zscore_distribution( df=stack_df, title=f"Combined Omics Z-score Distribution for {context}", output_png_filepath=output_png_filepath, From a509786c93f1ba762ac35053715bd4abfdce5cbd Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Wed, 25 Dec 2024 17:10:35 -0600 Subject: [PATCH 031/265] fix: hotfix - zscore ceiling is incorrect Signed-off-by: Josh Loecker --- main/como/merge_xomics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index f15654df..f58a69b3 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -469,7 +469,7 @@ async def merge_xomics( # noqa: C901 adjust_for_na: bool = False, merge_zfpkm_distribution: bool = False, weighted_z_floor: int = -6, - weighted_z_ceiling: int = -6, + weighted_z_ceiling: int = 6, ): """Merge expression tables of multiple sources (RNA-seq, proteomics) into one.""" if expression_requirement < 1: From 941e07302cecfd7c5e14fcbd6d6c2bbba43b4d4b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 14:47:30 -0600 Subject: [PATCH 032/265] chore(deps): bump astral-sh/ruff-action from 2 to 3 (#213) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/continuous_integration.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 113c905d..6cc5eb38 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -26,17 +26,17 @@ jobs: run: uv run jupyter nbconvert --clear-output --inplace "main/COMO.ipynb" - name: Format Python Imports - uses: astral-sh/ruff-action@v2 + uses: astral-sh/ruff-action@v3 with: args: "check --fix --select I" - name: Format code - uses: astral-sh/ruff-action@v2 + uses: astral-sh/ruff-action@v3 with: args: "format" - name: Format Notebook - uses: astral-sh/ruff-action@v2 + uses: astral-sh/ruff-action@v3 with: args: "format main/COMO.ipynb" @@ -54,7 +54,7 @@ jobs: uses: actions/checkout@v4 - name: Check Lint - uses: astral-sh/ruff-action@v2 + uses: astral-sh/ruff-action@v3 with: args: "check --no-fix --verbose" From fdfd0ece56d9715749726a8faf9c9305af293034 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 20:48:30 +0000 Subject: [PATCH 033/265] chore(deps): bump astral-sh/setup-uv from 4 to 5 Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 4 to 5. - [Release notes](https://github.com/astral-sh/setup-uv/releases) - [Commits](https://github.com/astral-sh/setup-uv/compare/v4...v5) --- updated-dependencies: - dependency-name: astral-sh/setup-uv dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/continuous_integration.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 6cc5eb38..bdc7b156 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -14,7 +14,7 @@ jobs: uses: actions/checkout@v4 - name: Install uv - uses: astral-sh/setup-uv@v4 + uses: astral-sh/setup-uv@v5 - name: Create Virtual Environment run: uv venv @@ -68,7 +68,7 @@ jobs: uses: actions/checkout@v4 - name: Install uv - uses: astral-sh/setup-uv@v4 + uses: astral-sh/setup-uv@v5 with: enable-cache: "true" cache-suffix: "${{ matrix.python-version }}" From fb384eca1c5f6371e6e5a694f45f88bf9bafa015 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 13:46:47 -0600 Subject: [PATCH 034/265] fix: pin numpy to less than version 2; update scanpy Signed-off-by: Josh Loecker --- pyproject.toml | 5 +- uv.lock | 300 +++++++++++++++++-------------------------------- 2 files changed, 108 insertions(+), 197 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index ea9a3299..70ceb3e8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,10 +14,11 @@ dependencies = [ "fast-bioservices>=0.3.9", "kaleido==0.2.1", "loguru>=0.7.2", + "numpy<2.0", "openpyxl>=3.1.5", "pandas>=1.3.5", "plotly>=5.24.1", - "scanpy>=1.9.8", + "scanpy>=1.10.4", "scikit-learn>=1.5.2", "scipy>=1.7.3", "setuptools<60.0", @@ -58,4 +59,4 @@ name = "cz_conventional_commits" tag_format = "$version" version_scheme = "semver2" version_provider = "pep621" -update_changelog_on_bump = true \ No newline at end of file +update_changelog_on_bump = true diff --git a/uv.lock b/uv.lock index 4ccb715f..7d354a68 100644 --- a/uv.lock +++ b/uv.lock @@ -33,12 +33,10 @@ dependencies = [ { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, { name = "h5py" }, { name = "natsort" }, - { name = "numpy", version = "1.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, { name = "packaging" }, { name = "pandas" }, - { name = "scipy", version = "1.7.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "scipy", version = "1.14.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "scipy" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c1/40/8e8c3baca1b00f107cdd2f9b376bcf97de1a7912786b7b4012343228d143/anndata-0.10.5.post1.tar.gz", hash = "sha256:9a17c6eda9fc40759b3f5f81742f5d18c1a0a1acdf02f13e1646700ec082c155", size = 163852 } wheels = [ @@ -340,13 +338,11 @@ dependencies = [ { name = "boolean-py" }, { name = "indexed" }, { name = "matplotlib" }, - { name = "numpy", version = "1.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, { name = "optlang" }, { name = "pandas" }, { name = "pathos" }, - { name = "scipy", version = "1.7.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "scipy", version = "1.14.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "scipy" }, ] [[package]] @@ -360,8 +356,7 @@ dependencies = [ { name = "future" }, { name = "httpx" }, { name = "importlib-resources" }, - { name = "numpy", version = "1.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, { name = "optlang" }, { name = "pandas" }, { name = "pydantic" }, @@ -439,13 +434,13 @@ dependencies = [ { name = "fast-bioservices" }, { name = "kaleido" }, { name = "loguru" }, + { name = "numpy" }, { name = "openpyxl" }, { name = "pandas" }, { name = "plotly" }, { name = "scanpy" }, { name = "scikit-learn" }, - { name = "scipy", version = "1.7.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "scipy", version = "1.14.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "scipy" }, { name = "setuptools" }, { name = "troppo" }, ] @@ -483,6 +478,7 @@ requires-dist = [ { name = "jupyterlab", marker = "extra == 'interactive'", specifier = ">=4.3.2" }, { name = "kaleido", specifier = "==0.2.1" }, { name = "loguru", specifier = ">=0.7.2" }, + { name = "numpy", specifier = "<2.0" }, { name = "openpyxl", specifier = ">=3.1.5" }, { name = "pandas", specifier = ">=1.3.5" }, { name = "plotly", specifier = ">=5.24.1" }, @@ -490,7 +486,7 @@ requires-dist = [ { name = "pytest-asyncio", marker = "extra == 'dev'", specifier = ">=0.24.0" }, { name = "pytest-cov", marker = "extra == 'dev'", specifier = ">=6.0.0" }, { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.8.0" }, - { name = "scanpy", specifier = ">=1.9.8" }, + { name = "scanpy", specifier = ">=1.10.4" }, { name = "scikit-learn", specifier = ">=1.5.2" }, { name = "scipy", specifier = ">=1.7.3" }, { name = "setuptools", specifier = "<60.0" }, @@ -502,8 +498,7 @@ name = "contourpy" version = "1.2.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy", version = "1.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, ] sdist = { url = "https://files.pythonhosted.org/packages/8d/9e/e4786569b319847ffd98a8326802d5cf8a5500860dbfc2df1f0f4883ed99/contourpy-1.2.1.tar.gz", hash = "sha256:4d8908b3bee1c889e547867ca4cdc54e5ab6be6d3e078556814a22457f49423c", size = 13457196 } wheels = [ @@ -804,8 +799,7 @@ name = "h5py" version = "3.12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy", version = "1.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cc/0c/5c2b0a88158682aeafb10c1c2b735df5bc31f165bfe192f2ee9f2a23b5f1/h5py-3.12.1.tar.gz", hash = "sha256:326d70b53d31baa61f00b8aa5f95c2fcb9621a3ee8365d770c551a13dbbcbfdf", size = 411457 } wheels = [ @@ -921,7 +915,7 @@ name = "ipykernel" version = "6.29.5" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "appnope", marker = "platform_system == 'Darwin'" }, + { name = "appnope", marker = "sys_platform == 'darwin'" }, { name = "comm" }, { name = "debugpy" }, { name = "ipython" }, @@ -1294,35 +1288,35 @@ wheels = [ ] [[package]] -name = "llvmlite" -version = "0.36.0" +name = "legacy-api-wrap" +version = "1.4.1" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version == '3.11.*'", - "python_full_version >= '3.12'", +sdist = { url = "https://files.pythonhosted.org/packages/a4/07/fbc3cf8cf3759c5f234af9d94761f09f41e6d0aa912b2a9dfda19a48855a/legacy_api_wrap-1.4.1.tar.gz", hash = "sha256:9c40d67aa8312fec8763e87cbf28fea4b67710c79ca7a18137b573d150f3b2b4", size = 11003 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/1d/9324c70629dfe4395f9122ab331cf245d3cce6ded851aa8a0a8ae264c4e6/legacy_api_wrap-1.4.1-py3-none-any.whl", hash = "sha256:8ba214242e836cebfd3b64c1a1653fce955abb0f9e4c7dffb51f2ad014def0eb", size = 9986 }, ] -sdist = { url = "https://files.pythonhosted.org/packages/19/66/6b2c49c7c68da48d17059882fdb9ad9ac9e5ac3f22b00874d7996e3c44a8/llvmlite-0.36.0.tar.gz", hash = "sha256:765128fdf5f149ed0b889ffbe2b05eb1717f8e20a5c87fa2b4018fbcce0fcfc9", size = 126219 } [[package]] name = "llvmlite" -version = "0.41.1" +version = "0.43.0" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.11'", -] -sdist = { url = "https://files.pythonhosted.org/packages/01/c6/bc6634da9f58edf91a1a002280c6380f404715245a49a46234b1d9d9585a/llvmlite-0.41.1.tar.gz", hash = "sha256:f19f767a018e6ec89608e1f6b13348fa2fcde657151137cb64e56d48598a92db", size = 146564 } +sdist = { url = "https://files.pythonhosted.org/packages/9f/3d/f513755f285db51ab363a53e898b85562e950f79a2e6767a364530c2f645/llvmlite-0.43.0.tar.gz", hash = "sha256:ae2b5b5c3ef67354824fb75517c8db5fbe93bc02cd9671f3c62271626bc041d5", size = 157069 } wheels = [ - { url = "https://files.pythonhosted.org/packages/10/e2/931d2d35350d3c375d6c43a04982fb5d8f90c15002de024a814d919a1e67/llvmlite-0.41.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c1e1029d47ee66d3a0c4d6088641882f75b93db82bd0e6178f7bd744ebce42b9", size = 31032708 }, - { url = "https://files.pythonhosted.org/packages/47/d5/2d6261a47dd6b1005d60a6e37a3de007ddc15a297f146ee905605e3cbc3e/llvmlite-0.41.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:150d0bc275a8ac664a705135e639178883293cf08c1a38de3bbaa2f693a0a867", size = 28753858 }, - { url = "https://files.pythonhosted.org/packages/da/5e/afce5c757df730be7706ae671f5fce2cacdf4e46eed2b1a916e595453388/llvmlite-0.41.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1eee5cf17ec2b4198b509272cf300ee6577229d237c98cc6e63861b08463ddc6", size = 42623412 }, - { url = "https://files.pythonhosted.org/packages/57/7d/ef28d5812f852b93bd2a583d00cdcde56833d31b645ae0eaa7e71eecfb4e/llvmlite-0.41.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dd0338da625346538f1173a17cabf21d1e315cf387ca21b294ff209d176e244", size = 43623334 }, - { url = "https://files.pythonhosted.org/packages/48/39/7db84e829b874f90316e9f6d7497f761b9a645abe61f8c9588b292876314/llvmlite-0.41.1-cp310-cp310-win32.whl", hash = "sha256:fa1469901a2e100c17eb8fe2678e34bd4255a3576d1a543421356e9c14d6e2ae", size = 23414330 }, - { url = "https://files.pythonhosted.org/packages/1f/05/cfc9c51aff9adbb6f7df93df3fb20100ee5d9c3d0445ade3df8057e50b0a/llvmlite-0.41.1-cp310-cp310-win_amd64.whl", hash = "sha256:2b76acee82ea0e9304be6be9d4b3840208d050ea0dcad75b1635fa06e949a0ae", size = 28108282 }, - { url = "https://files.pythonhosted.org/packages/96/e0/54b0a58969b208b3a66ed30f560e127f52c3add6027b8e67d0a00ea0b178/llvmlite-0.41.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:210e458723436b2469d61b54b453474e09e12a94453c97ea3fbb0742ba5a83d8", size = 31032706 }, - { url = "https://files.pythonhosted.org/packages/12/f4/9bc78ef5d52cbe595a849d332c872583a6294afff6f5317de6dce4abbe55/llvmlite-0.41.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:855f280e781d49e0640aef4c4af586831ade8f1a6c4df483fb901cbe1a48d127", size = 28753841 }, - { url = "https://files.pythonhosted.org/packages/b5/b0/48caac8ea81d6a11a1917dd98258ea67c9b8a78a31fa45b89ae6aa94e678/llvmlite-0.41.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b67340c62c93a11fae482910dc29163a50dff3dfa88bc874872d28ee604a83be", size = 42623411 }, - { url = "https://files.pythonhosted.org/packages/0a/dd/e10658cb0e4ad8364b37ae2a6187ebb6b3b35e08b36ef9e98790b9f2f437/llvmlite-0.41.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2181bb63ef3c607e6403813421b46982c3ac6bfc1f11fa16a13eaafb46f578e6", size = 43623334 }, - { url = "https://files.pythonhosted.org/packages/14/fe/d3a9c921a2adad2e9f24693754983f290e0dac9410666e802b9dba4d0218/llvmlite-0.41.1-cp311-cp311-win_amd64.whl", hash = "sha256:9564c19b31a0434f01d2025b06b44c7ed422f51e719ab5d24ff03b7560066c9a", size = 28092676 }, + { url = "https://files.pythonhosted.org/packages/23/ff/6ca7e98998b573b4bd6566f15c35e5c8bea829663a6df0c7aa55ab559da9/llvmlite-0.43.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a289af9a1687c6cf463478f0fa8e8aa3b6fb813317b0d70bf1ed0759eab6f761", size = 31064408 }, + { url = "https://files.pythonhosted.org/packages/ca/5c/a27f9257f86f0cda3f764ff21d9f4217b9f6a0d45e7a39ecfa7905f524ce/llvmlite-0.43.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d4fd101f571a31acb1559ae1af30f30b1dc4b3186669f92ad780e17c81e91bc", size = 28793153 }, + { url = "https://files.pythonhosted.org/packages/7e/3c/4410f670ad0a911227ea2ecfcba9f672a77cf1924df5280c4562032ec32d/llvmlite-0.43.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d434ec7e2ce3cc8f452d1cd9a28591745de022f931d67be688a737320dfcead", size = 42857276 }, + { url = "https://files.pythonhosted.org/packages/c6/21/2ffbab5714e72f2483207b4a1de79b2eecd9debbf666ff4e7067bcc5c134/llvmlite-0.43.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6912a87782acdff6eb8bf01675ed01d60ca1f2551f8176a300a886f09e836a6a", size = 43871781 }, + { url = "https://files.pythonhosted.org/packages/f2/26/b5478037c453554a61625ef1125f7e12bb1429ae11c6376f47beba9b0179/llvmlite-0.43.0-cp310-cp310-win_amd64.whl", hash = "sha256:14f0e4bf2fd2d9a75a3534111e8ebeb08eda2f33e9bdd6dfa13282afacdde0ed", size = 28123487 }, + { url = "https://files.pythonhosted.org/packages/95/8c/de3276d773ab6ce3ad676df5fab5aac19696b2956319d65d7dd88fb10f19/llvmlite-0.43.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3e8d0618cb9bfe40ac38a9633f2493d4d4e9fcc2f438d39a4e854f39cc0f5f98", size = 31064409 }, + { url = "https://files.pythonhosted.org/packages/ee/e1/38deed89ced4cf378c61e232265cfe933ccde56ae83c901aa68b477d14b1/llvmlite-0.43.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0a9a1a39d4bf3517f2af9d23d479b4175ead205c592ceeb8b89af48a327ea57", size = 28793149 }, + { url = "https://files.pythonhosted.org/packages/2f/b2/4429433eb2dc8379e2cb582502dca074c23837f8fd009907f78a24de4c25/llvmlite-0.43.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1da416ab53e4f7f3bc8d4eeba36d801cc1894b9fbfbf2022b29b6bad34a7df2", size = 42857277 }, + { url = "https://files.pythonhosted.org/packages/6b/99/5d00a7d671b1ba1751fc9f19d3b36f3300774c6eebe2bcdb5f6191763eb4/llvmlite-0.43.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:977525a1e5f4059316b183fb4fd34fa858c9eade31f165427a3977c95e3ee749", size = 43871781 }, + { url = "https://files.pythonhosted.org/packages/20/ab/ed5ed3688c6ba4f0b8d789da19fd8e30a9cf7fc5852effe311bc5aefe73e/llvmlite-0.43.0-cp311-cp311-win_amd64.whl", hash = "sha256:d5bd550001d26450bd90777736c69d68c487d17bf371438f975229b2b8241a91", size = 28107433 }, + { url = "https://files.pythonhosted.org/packages/0b/67/9443509e5d2b6d8587bae3ede5598fa8bd586b1c7701696663ea8af15b5b/llvmlite-0.43.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f99b600aa7f65235a5a05d0b9a9f31150c390f31261f2a0ba678e26823ec38f7", size = 31064409 }, + { url = "https://files.pythonhosted.org/packages/a2/9c/24139d3712d2d352e300c39c0e00d167472c08b3bd350c3c33d72c88ff8d/llvmlite-0.43.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:35d80d61d0cda2d767f72de99450766250560399edc309da16937b93d3b676e7", size = 28793145 }, + { url = "https://files.pythonhosted.org/packages/bf/f1/4c205a48488e574ee9f6505d50e84370a978c90f08dab41a42d8f2c576b6/llvmlite-0.43.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eccce86bba940bae0d8d48ed925f21dbb813519169246e2ab292b5092aba121f", size = 42857276 }, + { url = "https://files.pythonhosted.org/packages/00/5f/323c4d56e8401c50185fd0e875fcf06b71bf825a863699be1eb10aa2a9cb/llvmlite-0.43.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df6509e1507ca0760787a199d19439cc887bfd82226f5af746d6977bd9f66844", size = 43871781 }, + { url = "https://files.pythonhosted.org/packages/c6/94/dea10e263655ce78d777e78d904903faae39d1fc440762be4a9dc46bed49/llvmlite-0.43.0-cp312-cp312-win_amd64.whl", hash = "sha256:7a2872ee80dcf6b5dbdc838763d26554c2a18aa833d31a2635bff16aafefb9c9", size = 28107442 }, ] [[package]] @@ -1397,8 +1391,7 @@ dependencies = [ { name = "cycler" }, { name = "fonttools" }, { name = "kiwisolver" }, - { name = "numpy", version = "1.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, { name = "packaging" }, { name = "pillow" }, { name = "pyparsing" }, @@ -1581,106 +1574,61 @@ wheels = [ [[package]] name = "numba" -version = "0.53.1" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version == '3.11.*'", - "python_full_version >= '3.12'", -] -dependencies = [ - { name = "llvmlite", version = "0.36.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "numpy", version = "2.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "setuptools", marker = "python_full_version >= '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/e3/7d/3d61160836e49f40913741c464f119551c15ed371c1d91ea50308495b93b/numba-0.53.1.tar.gz", hash = "sha256:9cd4e5216acdc66c4e9dab2dfd22ddb5bef151185c070d4a3cd8e78638aff5b0", size = 2213956 } - -[[package]] -name = "numba" -version = "0.58.0" +version = "0.60.0" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.11'", -] dependencies = [ - { name = "llvmlite", version = "0.41.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "1.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/c6/95/985695c7355606dc631f0ba75609e004aa5d36dc5d3d56fbb5a747a214df/numba-0.58.0.tar.gz", hash = "sha256:e5d5a318dc65a101ef846d7fd93f3cf2f7942494019e8342e51238b360739125", size = 2623297 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4a/1d/ecc1948837253fd3f7a99b720838602396fcee765d614d1a38e9de15aea7/numba-0.58.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f146c11af62ad25021d93fccf48715a96d1ea76d43c1c3bc97dca561c6a2693", size = 2587983 }, - { url = "https://files.pythonhosted.org/packages/1e/72/cd55b7091ce87f74dfc4c48255d4f85708486a3ccced3ecd1b3a52501c54/numba-0.58.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8059ee491651885f89655f08856a107aa610e3355b373f3b7437f1da96f09703", size = 2590803 }, - { url = "https://files.pythonhosted.org/packages/28/e7/d759f11023e7b951a7d192426335a6e5906b1c7c5a088dac5ab6fcd14261/numba-0.58.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8bd9edd27ab29e80bcf4083f9955c4a8871075a13a370b3bef99f81e184541fa", size = 3349361 }, - { url = "https://files.pythonhosted.org/packages/e7/69/d228b38ffb70858d74538bdfe5aa18c7640b7f07840239690985b3a94009/numba-0.58.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7ee9f5fd962e0ada0e68df67a6ff881f95b45e0ae7cb96141e913337040d490b", size = 3641029 }, - { url = "https://files.pythonhosted.org/packages/98/59/96974273437b61fd4bf5ccd36c6e80e1baa3440191e8c21521d713b28fbb/numba-0.58.0-cp310-cp310-win_amd64.whl", hash = "sha256:398ab539257df8e980ec2f9cdfae836bb965fadc2dd30db3fcfbf3aefa542836", size = 2605912 }, - { url = "https://files.pythonhosted.org/packages/c6/14/7399ae5b4d74301cfaf596ef9fd02041bbcc8fc5e8df184d881afc0de809/numba-0.58.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e61a1fa0ab7d290f0a43d8523b372f96765db6ceb6a691660c17e9ed609cb470", size = 2587673 }, - { url = "https://files.pythonhosted.org/packages/1b/2e/1d80831b015606a6743ea4bf60ab1c91e7130ff1155381524a1dab0e8334/numba-0.58.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8a9b69cc6259131791822c5eb893b03cd9372f4aae669d020500565b6d5d80bc", size = 2590525 }, - { url = "https://files.pythonhosted.org/packages/32/90/75102d27740632bc6f5b3fb9d3fea86135637af4533a2cb373b793bf36ca/numba-0.58.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e7b42b23c36cf08fcfe1a8f2acf3a0af95b41f9ee07fc81b28d7b9b5ada85d8c", size = 3354706 }, - { url = "https://files.pythonhosted.org/packages/f7/b6/8800604a3380aa94af830c30839db93077c7fe2812a48ce7d4400d75ba9c/numba-0.58.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0d7a5e81e4047a23986f816b48ac46616ceb4eadbff6bbe739944d36b3bdbfe7", size = 3646689 }, - { url = "https://files.pythonhosted.org/packages/e8/1c/5d65ac922a4f9a6f90a10207b818e22e4d48a782af6574a6e7a50fae074d/numba-0.58.0-cp311-cp311-win_amd64.whl", hash = "sha256:0ce322178ff7006b7f50dad25b042ef64c6393f2fafafa79c0498d789b1aac27", size = 2605876 }, -] - -[[package]] -name = "numpy" -version = "1.22.4" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.11'", + { name = "llvmlite" }, + { name = "numpy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f6/d8/ab692a75f584d13c6542c3994f75def5bce52ded9399f52e230fe402819d/numpy-1.22.4.zip", hash = "sha256:425b390e4619f58d8526b3dcf656dde069133ae5c240229821f01b5f44ea07af", size = 11458830 } +sdist = { url = "https://files.pythonhosted.org/packages/3c/93/2849300a9184775ba274aba6f82f303343669b0592b7bb0849ea713dabb0/numba-0.60.0.tar.gz", hash = "sha256:5df6158e5584eece5fc83294b949fd30b9f1125df7708862205217e068aabf16", size = 2702171 } wheels = [ - { url = "https://files.pythonhosted.org/packages/d0/4a/5677dc12d2b0c2f9fa901cc43b3f6b8d99ddac00fcfca93e9989bca1d93c/numpy-1.22.4-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:ba9ead61dfb5d971d77b6c131a9dbee62294a932bf6a356e48c75ae684e635b3", size = 17649001 }, - { url = "https://files.pythonhosted.org/packages/95/6a/319e9fafb828e4a651b03b9622b781dfd80b5f1f5f31cfa6c9b734ce7cda/numpy-1.22.4-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:1ce7ab2053e36c0a71e7a13a7475bd3b1f54750b4b433adc96313e127b870887", size = 17652668 }, - { url = "https://files.pythonhosted.org/packages/9b/12/14529e4a0749c165c2f9df5cb09873f35ffe1bac7cfdf9a26fe90bfd587a/numpy-1.22.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7228ad13744f63575b3a972d7ee4fd61815b2879998e70930d4ccf9ec721dce0", size = 12761458 }, - { url = "https://files.pythonhosted.org/packages/91/18/7949972b5254f88f040f53dc6f019fcb21597d6f37f7446d71019acece03/numpy-1.22.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:43a8ca7391b626b4c4fe20aefe79fec683279e31e7c79716863b4b25021e0e74", size = 13348049 }, - { url = "https://files.pythonhosted.org/packages/b0/f4/d67c8c39efe3c45dfd32bb2a3fc49cbbe5496e575cc42b8bac60fe7b6701/numpy-1.22.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a911e317e8c826ea632205e63ed8507e0dc877dcdc49744584dfc363df9ca08c", size = 16817233 }, - { url = "https://files.pythonhosted.org/packages/2a/fa/f00ba4919bc06073af4c674b1ddc0c93d339abb2b2ec935136db8c55f87d/numpy-1.22.4-cp310-cp310-win32.whl", hash = "sha256:9ce7df0abeabe7fbd8ccbf343dc0db72f68549856b863ae3dd580255d009648e", size = 12222860 }, - { url = "https://files.pythonhosted.org/packages/b5/50/d7978137464251c393df28fe0592fbb968110f752d66f60c7a53f7158076/numpy-1.22.4-cp310-cp310-win_amd64.whl", hash = "sha256:3e1ffa4748168e1cc8d3cde93f006fe92b5421396221a02f2274aab6ac83b077", size = 14725999 }, + { url = "https://files.pythonhosted.org/packages/f7/cf/baa13a7e3556d73d9e38021e6d6aa4aeb30d8b94545aa8b70d0f24a1ccc4/numba-0.60.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5d761de835cd38fb400d2c26bb103a2726f548dc30368853121d66201672e651", size = 2647627 }, + { url = "https://files.pythonhosted.org/packages/ac/ba/4b57fa498564457c3cc9fc9e570a6b08e6086c74220f24baaf04e54b995f/numba-0.60.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:159e618ef213fba758837f9837fb402bbe65326e60ba0633dbe6c7f274d42c1b", size = 2650322 }, + { url = "https://files.pythonhosted.org/packages/28/98/7ea97ee75870a54f938a8c70f7e0be4495ba5349c5f9db09d467c4a5d5b7/numba-0.60.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1527dc578b95c7c4ff248792ec33d097ba6bef9eda466c948b68dfc995c25781", size = 3407390 }, + { url = "https://files.pythonhosted.org/packages/79/58/cb4ac5b8f7ec64200460aef1fed88258fb872ceef504ab1f989d2ff0f684/numba-0.60.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fe0b28abb8d70f8160798f4de9d486143200f34458d34c4a214114e445d7124e", size = 3699694 }, + { url = "https://files.pythonhosted.org/packages/1c/b0/c61a93ca947d12233ff45de506ddbf52af3f752066a0b8be4d27426e16da/numba-0.60.0-cp310-cp310-win_amd64.whl", hash = "sha256:19407ced081d7e2e4b8d8c36aa57b7452e0283871c296e12d798852bc7d7f198", size = 2687030 }, + { url = "https://files.pythonhosted.org/packages/98/ad/df18d492a8f00d29a30db307904b9b296e37507034eedb523876f3a2e13e/numba-0.60.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a17b70fc9e380ee29c42717e8cc0bfaa5556c416d94f9aa96ba13acb41bdece8", size = 2647254 }, + { url = "https://files.pythonhosted.org/packages/9a/51/a4dc2c01ce7a850b8e56ff6d5381d047a5daea83d12bad08aa071d34b2ee/numba-0.60.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3fb02b344a2a80efa6f677aa5c40cd5dd452e1b35f8d1c2af0dfd9ada9978e4b", size = 2649970 }, + { url = "https://files.pythonhosted.org/packages/f9/4c/8889ac94c0b33dca80bed11564b8c6d9ea14d7f094e674c58e5c5b05859b/numba-0.60.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5f4fde652ea604ea3c86508a3fb31556a6157b2c76c8b51b1d45eb40c8598703", size = 3412492 }, + { url = "https://files.pythonhosted.org/packages/57/03/2b4245b05b71c0cee667e6a0b51606dfa7f4157c9093d71c6b208385a611/numba-0.60.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4142d7ac0210cc86432b818338a2bc368dc773a2f5cf1e32ff7c5b378bd63ee8", size = 3705018 }, + { url = "https://files.pythonhosted.org/packages/79/89/2d924ca60dbf949f18a6fec223a2445f5f428d9a5f97a6b29c2122319015/numba-0.60.0-cp311-cp311-win_amd64.whl", hash = "sha256:cac02c041e9b5bc8cf8f2034ff6f0dbafccd1ae9590dc146b3a02a45e53af4e2", size = 2686920 }, + { url = "https://files.pythonhosted.org/packages/eb/5c/b5ec752c475e78a6c3676b67c514220dbde2725896bbb0b6ec6ea54b2738/numba-0.60.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d7da4098db31182fc5ffe4bc42c6f24cd7d1cb8a14b59fd755bfee32e34b8404", size = 2647866 }, + { url = "https://files.pythonhosted.org/packages/65/42/39559664b2e7c15689a638c2a38b3b74c6e69a04e2b3019b9f7742479188/numba-0.60.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:38d6ea4c1f56417076ecf8fc327c831ae793282e0ff51080c5094cb726507b1c", size = 2650208 }, + { url = "https://files.pythonhosted.org/packages/67/88/c4459ccc05674ef02119abf2888ccd3e2fed12a323f52255f4982fc95876/numba-0.60.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:62908d29fb6a3229c242e981ca27e32a6e606cc253fc9e8faeb0e48760de241e", size = 3466946 }, + { url = "https://files.pythonhosted.org/packages/8b/41/ac11cf33524def12aa5bd698226ae196a1185831c05ed29dc0c56eaa308b/numba-0.60.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0ebaa91538e996f708f1ab30ef4d3ddc344b64b5227b67a57aa74f401bb68b9d", size = 3761463 }, + { url = "https://files.pythonhosted.org/packages/ca/bd/0fe29fcd1b6a8de479a4ed25c6e56470e467e3611c079d55869ceef2b6d1/numba-0.60.0-cp312-cp312-win_amd64.whl", hash = "sha256:f75262e8fe7fa96db1dca93d53a194a38c46da28b112b8a4aca168f0df860347", size = 2707588 }, ] [[package]] name = "numpy" -version = "2.1.3" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version == '3.11.*'", - "python_full_version >= '3.12'", -] -sdist = { url = "https://files.pythonhosted.org/packages/25/ca/1166b75c21abd1da445b97bf1fa2f14f423c6cfb4fc7c4ef31dccf9f6a94/numpy-2.1.3.tar.gz", hash = "sha256:aa08e04e08aaf974d4458def539dece0d28146d866a39da5639596f4921fd761", size = 20166090 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f1/80/d572a4737626372915bca41c3afbfec9d173561a39a0a61bacbbfd1dafd4/numpy-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c894b4305373b9c5576d7a12b473702afdf48ce5369c074ba304cc5ad8730dff", size = 21152472 }, - { url = "https://files.pythonhosted.org/packages/6f/bb/7bfba10c791ae3bb6716da77ad85a82d5fac07fc96fb0023ef0571df9d20/numpy-2.1.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b47fbb433d3260adcd51eb54f92a2ffbc90a4595f8970ee00e064c644ac788f5", size = 13747967 }, - { url = "https://files.pythonhosted.org/packages/da/d6/2df7bde35f0478455f0be5934877b3e5a505f587b00230f54a519a6b55a5/numpy-2.1.3-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:825656d0743699c529c5943554d223c021ff0494ff1442152ce887ef4f7561a1", size = 5354921 }, - { url = "https://files.pythonhosted.org/packages/d1/bb/75b945874f931494891eac6ca06a1764d0e8208791f3addadb2963b83527/numpy-2.1.3-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:6a4825252fcc430a182ac4dee5a505053d262c807f8a924603d411f6718b88fd", size = 6888603 }, - { url = "https://files.pythonhosted.org/packages/68/a7/fde73636f6498dbfa6d82fc336164635fe592f1ad0d13285fcb6267fdc1c/numpy-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e711e02f49e176a01d0349d82cb5f05ba4db7d5e7e0defd026328e5cfb3226d3", size = 13889862 }, - { url = "https://files.pythonhosted.org/packages/05/db/5d9c91b2e1e2e72be1369278f696356d44975befcae830daf2e667dcb54f/numpy-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78574ac2d1a4a02421f25da9559850d59457bac82f2b8d7a44fe83a64f770098", size = 16328151 }, - { url = "https://files.pythonhosted.org/packages/3e/6a/7eb732109b53ae64a29e25d7e68eb9d6611037f6354875497008a49e74d3/numpy-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c7662f0e3673fe4e832fe07b65c50342ea27d989f92c80355658c7f888fcc83c", size = 16704107 }, - { url = "https://files.pythonhosted.org/packages/88/cc/278113b66a1141053cbda6f80e4200c6da06b3079c2d27bda1fde41f2c1f/numpy-2.1.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:fa2d1337dc61c8dc417fbccf20f6d1e139896a30721b7f1e832b2bb6ef4eb6c4", size = 14385789 }, - { url = "https://files.pythonhosted.org/packages/f5/69/eb20f5e1bfa07449bc67574d2f0f7c1e6b335fb41672e43861a7727d85f2/numpy-2.1.3-cp310-cp310-win32.whl", hash = "sha256:72dcc4a35a8515d83e76b58fdf8113a5c969ccd505c8a946759b24e3182d1f23", size = 6536706 }, - { url = "https://files.pythonhosted.org/packages/8e/8b/1c131ab5a94c1086c289c6e1da1d843de9dbd95fe5f5ee6e61904c9518e2/numpy-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:ecc76a9ba2911d8d37ac01de72834d8849e55473457558e12995f4cd53e778e0", size = 12864165 }, - { url = "https://files.pythonhosted.org/packages/ad/81/c8167192eba5247593cd9d305ac236847c2912ff39e11402e72ae28a4985/numpy-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4d1167c53b93f1f5d8a139a742b3c6f4d429b54e74e6b57d0eff40045187b15d", size = 21156252 }, - { url = "https://files.pythonhosted.org/packages/da/74/5a60003fc3d8a718d830b08b654d0eea2d2db0806bab8f3c2aca7e18e010/numpy-2.1.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c80e4a09b3d95b4e1cac08643f1152fa71a0a821a2d4277334c88d54b2219a41", size = 13784119 }, - { url = "https://files.pythonhosted.org/packages/47/7c/864cb966b96fce5e63fcf25e1e4d957fe5725a635e5f11fe03f39dd9d6b5/numpy-2.1.3-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:576a1c1d25e9e02ed7fa5477f30a127fe56debd53b8d2c89d5578f9857d03ca9", size = 5352978 }, - { url = "https://files.pythonhosted.org/packages/09/ac/61d07930a4993dd9691a6432de16d93bbe6aa4b1c12a5e573d468eefc1ca/numpy-2.1.3-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:973faafebaae4c0aaa1a1ca1ce02434554d67e628b8d805e61f874b84e136b09", size = 6892570 }, - { url = "https://files.pythonhosted.org/packages/27/2f/21b94664f23af2bb52030653697c685022119e0dc93d6097c3cb45bce5f9/numpy-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:762479be47a4863e261a840e8e01608d124ee1361e48b96916f38b119cfda04a", size = 13896715 }, - { url = "https://files.pythonhosted.org/packages/7a/f0/80811e836484262b236c684a75dfc4ba0424bc670e765afaa911468d9f39/numpy-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc6f24b3d1ecc1eebfbf5d6051faa49af40b03be1aaa781ebdadcbc090b4539b", size = 16339644 }, - { url = "https://files.pythonhosted.org/packages/fa/81/ce213159a1ed8eb7d88a2a6ef4fbdb9e4ffd0c76b866c350eb4e3c37e640/numpy-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:17ee83a1f4fef3c94d16dc1802b998668b5419362c8a4f4e8a491de1b41cc3ee", size = 16712217 }, - { url = "https://files.pythonhosted.org/packages/7d/84/4de0b87d5a72f45556b2a8ee9fc8801e8518ec867fc68260c1f5dcb3903f/numpy-2.1.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:15cb89f39fa6d0bdfb600ea24b250e5f1a3df23f901f51c8debaa6a5d122b2f0", size = 14399053 }, - { url = "https://files.pythonhosted.org/packages/7e/1c/e5fabb9ad849f9d798b44458fd12a318d27592d4bc1448e269dec070ff04/numpy-2.1.3-cp311-cp311-win32.whl", hash = "sha256:d9beb777a78c331580705326d2367488d5bc473b49a9bc3036c154832520aca9", size = 6534741 }, - { url = "https://files.pythonhosted.org/packages/1e/48/a9a4b538e28f854bfb62e1dea3c8fea12e90216a276c7777ae5345ff29a7/numpy-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:d89dd2b6da69c4fff5e39c28a382199ddedc3a5be5390115608345dec660b9e2", size = 12869487 }, - { url = "https://files.pythonhosted.org/packages/8a/f0/385eb9970309643cbca4fc6eebc8bb16e560de129c91258dfaa18498da8b/numpy-2.1.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f55ba01150f52b1027829b50d70ef1dafd9821ea82905b63936668403c3b471e", size = 20849658 }, - { url = "https://files.pythonhosted.org/packages/54/4a/765b4607f0fecbb239638d610d04ec0a0ded9b4951c56dc68cef79026abf/numpy-2.1.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:13138eadd4f4da03074851a698ffa7e405f41a0845a6b1ad135b81596e4e9958", size = 13492258 }, - { url = "https://files.pythonhosted.org/packages/bd/a7/2332679479c70b68dccbf4a8eb9c9b5ee383164b161bee9284ac141fbd33/numpy-2.1.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:a6b46587b14b888e95e4a24d7b13ae91fa22386c199ee7b418f449032b2fa3b8", size = 5090249 }, - { url = "https://files.pythonhosted.org/packages/c1/67/4aa00316b3b981a822c7a239d3a8135be2a6945d1fd11d0efb25d361711a/numpy-2.1.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:0fa14563cc46422e99daef53d725d0c326e99e468a9320a240affffe87852564", size = 6621704 }, - { url = "https://files.pythonhosted.org/packages/5e/da/1a429ae58b3b6c364eeec93bf044c532f2ff7b48a52e41050896cf15d5b1/numpy-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8637dcd2caa676e475503d1f8fdb327bc495554e10838019651b76d17b98e512", size = 13606089 }, - { url = "https://files.pythonhosted.org/packages/9e/3e/3757f304c704f2f0294a6b8340fcf2be244038be07da4cccf390fa678a9f/numpy-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2312b2aa89e1f43ecea6da6ea9a810d06aae08321609d8dc0d0eda6d946a541b", size = 16043185 }, - { url = "https://files.pythonhosted.org/packages/43/97/75329c28fea3113d00c8d2daf9bc5828d58d78ed661d8e05e234f86f0f6d/numpy-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a38c19106902bb19351b83802531fea19dee18e5b37b36454f27f11ff956f7fc", size = 16410751 }, - { url = "https://files.pythonhosted.org/packages/ad/7a/442965e98b34e0ae9da319f075b387bcb9a1e0658276cc63adb8c9686f7b/numpy-2.1.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:02135ade8b8a84011cbb67dc44e07c58f28575cf9ecf8ab304e51c05528c19f0", size = 14082705 }, - { url = "https://files.pythonhosted.org/packages/ac/b6/26108cf2cfa5c7e03fb969b595c93131eab4a399762b51ce9ebec2332e80/numpy-2.1.3-cp312-cp312-win32.whl", hash = "sha256:e6988e90fcf617da2b5c78902fe8e668361b43b4fe26dbf2d7b0f8034d4cafb9", size = 6239077 }, - { url = "https://files.pythonhosted.org/packages/a6/84/fa11dad3404b7634aaab50733581ce11e5350383311ea7a7010f464c0170/numpy-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:0d30c543f02e84e92c4b1f415b7c6b5326cbe45ee7882b6b77db7195fb971e3a", size = 12566858 }, - { url = "https://files.pythonhosted.org/packages/00/e7/8d8bb791b62586cc432ecbb70632b4f23b7b7c88df41878de7528264f6d7/numpy-2.1.3-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:4f2015dfe437dfebbfce7c85c7b53d81ba49e71ba7eadbf1df40c915af75979f", size = 20983893 }, - { url = "https://files.pythonhosted.org/packages/5e/f3/cb8118a044b5007586245a650360c9f5915b2f4232dd7658bb7a63dd1d02/numpy-2.1.3-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:3522b0dfe983a575e6a9ab3a4a4dfe156c3e428468ff08ce582b9bb6bd1d71d4", size = 6752501 }, - { url = "https://files.pythonhosted.org/packages/53/f5/365b46439b518d2ec6ebb880cc0edf90f225145dfd4db7958334f7164530/numpy-2.1.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c006b607a865b07cd981ccb218a04fc86b600411d83d6fc261357f1c0966755d", size = 16142601 }, - { url = "https://files.pythonhosted.org/packages/03/c2/d1fee6ba999aa7cd41ca6856937f2baaf604c3eec1565eae63451ec31e5e/numpy-2.1.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e14e26956e6f1696070788252dcdff11b4aca4c3e8bd166e0df1bb8f315a67cb", size = 12771397 }, +version = "1.26.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/65/6e/09db70a523a96d25e115e71cc56a6f9031e7b8cd166c1ac8438307c14058/numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010", size = 15786129 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/94/ace0fdea5241a27d13543ee117cbc65868e82213fb31a8eb7fe9ff23f313/numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0", size = 20631468 }, + { url = "https://files.pythonhosted.org/packages/20/f7/b24208eba89f9d1b58c1668bc6c8c4fd472b20c45573cb767f59d49fb0f6/numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a", size = 13966411 }, + { url = "https://files.pythonhosted.org/packages/fc/a5/4beee6488160798683eed5bdb7eead455892c3b4e1f78d79d8d3f3b084ac/numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4", size = 14219016 }, + { url = "https://files.pythonhosted.org/packages/4b/d7/ecf66c1cd12dc28b4040b15ab4d17b773b87fa9d29ca16125de01adb36cd/numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f", size = 18240889 }, + { url = "https://files.pythonhosted.org/packages/24/03/6f229fe3187546435c4f6f89f6d26c129d4f5bed40552899fcf1f0bf9e50/numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a", size = 13876746 }, + { url = "https://files.pythonhosted.org/packages/39/fe/39ada9b094f01f5a35486577c848fe274e374bbf8d8f472e1423a0bbd26d/numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2", size = 18078620 }, + { url = "https://files.pythonhosted.org/packages/d5/ef/6ad11d51197aad206a9ad2286dc1aac6a378059e06e8cf22cd08ed4f20dc/numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07", size = 5972659 }, + { url = "https://files.pythonhosted.org/packages/19/77/538f202862b9183f54108557bfda67e17603fc560c384559e769321c9d92/numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5", size = 15808905 }, + { url = "https://files.pythonhosted.org/packages/11/57/baae43d14fe163fa0e4c47f307b6b2511ab8d7d30177c491960504252053/numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71", size = 20630554 }, + { url = "https://files.pythonhosted.org/packages/1a/2e/151484f49fd03944c4a3ad9c418ed193cfd02724e138ac8a9505d056c582/numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef", size = 13997127 }, + { url = "https://files.pythonhosted.org/packages/79/ae/7e5b85136806f9dadf4878bf73cf223fe5c2636818ba3ab1c585d0403164/numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e", size = 14222994 }, + { url = "https://files.pythonhosted.org/packages/3a/d0/edc009c27b406c4f9cbc79274d6e46d634d139075492ad055e3d68445925/numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5", size = 18252005 }, + { url = "https://files.pythonhosted.org/packages/09/bf/2b1aaf8f525f2923ff6cfcf134ae5e750e279ac65ebf386c75a0cf6da06a/numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a", size = 13885297 }, + { url = "https://files.pythonhosted.org/packages/df/a0/4e0f14d847cfc2a633a1c8621d00724f3206cfeddeb66d35698c4e2cf3d2/numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a", size = 18093567 }, + { url = "https://files.pythonhosted.org/packages/d2/b7/a734c733286e10a7f1a8ad1ae8c90f2d33bf604a96548e0a4a3a6739b468/numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20", size = 5968812 }, + { url = "https://files.pythonhosted.org/packages/3f/6b/5610004206cf7f8e7ad91c5a85a8c71b2f2f8051a0c0c4d5916b76d6cbb2/numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2", size = 15811913 }, + { url = "https://files.pythonhosted.org/packages/95/12/8f2020a8e8b8383ac0177dc9570aad031a3beb12e38847f7129bacd96228/numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218", size = 20335901 }, + { url = "https://files.pythonhosted.org/packages/75/5b/ca6c8bd14007e5ca171c7c03102d17b4f4e0ceb53957e8c44343a9546dcc/numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b", size = 13685868 }, + { url = "https://files.pythonhosted.org/packages/79/f8/97f10e6755e2a7d027ca783f63044d5b1bc1ae7acb12afe6a9b4286eac17/numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b", size = 13925109 }, + { url = "https://files.pythonhosted.org/packages/0f/50/de23fde84e45f5c4fda2488c759b69990fd4512387a8632860f3ac9cd225/numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed", size = 17950613 }, + { url = "https://files.pythonhosted.org/packages/4c/0c/9c603826b6465e82591e05ca230dfc13376da512b25ccd0894709b054ed0/numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a", size = 13572172 }, + { url = "https://files.pythonhosted.org/packages/76/8c/2ba3902e1a0fc1c74962ea9bb33a534bb05984ad7ff9515bf8d07527cadd/numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0", size = 17786643 }, + { url = "https://files.pythonhosted.org/packages/28/4a/46d9e65106879492374999e76eb85f87b15328e06bd1550668f79f7b18c6/numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110", size = 5677803 }, + { url = "https://files.pythonhosted.org/packages/16/2e/86f24451c2d530c88daf997cb8d6ac622c1d40d19f5a031ed68a4b73a374/numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818", size = 15517754 }, ] [[package]] @@ -1732,8 +1680,7 @@ name = "pandas" version = "2.2.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy", version = "1.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, { name = "python-dateutil" }, { name = "pytz" }, { name = "tzdata" }, @@ -1801,8 +1748,7 @@ name = "patsy" version = "0.5.6" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy", version = "1.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, { name = "six" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c6/18/12e76e52d589c4a812a2f1fb2406b486c226b7ac263ac8ef4b5f4bb04058/patsy-0.5.6.tar.gz", hash = "sha256:95c6d47a7222535f84bff7f63d7303f2e297747a598db89cf5c67f0c0c7d2cdb", size = 398011 } @@ -2072,13 +2018,10 @@ version = "0.5.13" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "joblib" }, - { name = "llvmlite", version = "0.36.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "llvmlite", version = "0.41.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numba", version = "0.53.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "numba", version = "0.58.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "llvmlite" }, + { name = "numba" }, { name = "scikit-learn" }, - { name = "scipy", version = "1.7.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "scipy", version = "1.14.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "scipy" }, ] sdist = { url = "https://files.pythonhosted.org/packages/7e/58/560a4db5eb3794d922fe55804b10326534ded3d971e1933c1eef91193f5e/pynndescent-0.5.13.tar.gz", hash = "sha256:d74254c0ee0a1eeec84597d5fe89fedcf778593eeabe32c2f97412934a9800fb", size = 2975955 } wheels = [ @@ -2524,34 +2467,33 @@ wheels = [ [[package]] name = "scanpy" -version = "1.9.8" +version = "1.10.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anndata" }, { name = "h5py" }, { name = "joblib" }, + { name = "legacy-api-wrap" }, { name = "matplotlib" }, { name = "natsort" }, { name = "networkx" }, - { name = "numba", version = "0.53.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "numba", version = "0.58.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "1.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numba" }, + { name = "numpy" }, { name = "packaging" }, { name = "pandas" }, { name = "patsy" }, + { name = "pynndescent" }, { name = "scikit-learn" }, - { name = "scipy", version = "1.7.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "scipy", version = "1.14.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "scipy" }, { name = "seaborn" }, { name = "session-info" }, { name = "statsmodels" }, { name = "tqdm" }, { name = "umap-learn" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/84/95/2dad7cb2ce41aa433169f189d98d9d17e8eb6dfc5b02c7200fc69e9805c0/scanpy-1.9.8.tar.gz", hash = "sha256:2ab1790d2b82eadb0cf8d487f468beac7a8f6a3a8fd7112d1ae989f8c52a4353", size = 4592581 } +sdist = { url = "https://files.pythonhosted.org/packages/fd/cb/213db09685b572ef6470a5fa9199653949e7842e32c12f6dd1a55d80fea6/scanpy-1.10.4.tar.gz", hash = "sha256:2682fbbe2e4106c349472feebef08e174062fb666db4c94123758c6a7a470396", size = 13638355 } wheels = [ - { url = "https://files.pythonhosted.org/packages/3b/72/436046ca332b933ca7d09cd45b86154232203e068e8307a102d5349e9444/scanpy-1.9.8-py3-none-any.whl", hash = "sha256:abcca12dfe6975146277b6a76841e2328e07c6a9f518d234ba6a889b26b456dc", size = 2034053 }, + { url = "https://files.pythonhosted.org/packages/d1/b4/c408bac643afd670d2009219dbbb2076290e23fb1986937825c9a0d839c5/scanpy-1.10.4-py3-none-any.whl", hash = "sha256:d93256d0e8e6e34639ff9bf20bdde0162b5162c6f18f151d90b3eb9ea54ff03a", size = 2085671 }, ] [[package]] @@ -2560,10 +2502,8 @@ version = "1.5.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "joblib" }, - { name = "numpy", version = "1.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "scipy", version = "1.7.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "scipy", version = "1.14.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, + { name = "scipy" }, { name = "threadpoolctl" }, ] sdist = { url = "https://files.pythonhosted.org/packages/37/59/44985a2bdc95c74e34fef3d10cb5d93ce13b0e2a7baefffe1b53853b502d/scikit_learn-1.5.2.tar.gz", hash = "sha256:b4237ed7b3fdd0a4882792e68ef2545d5baa50aca3bb45aa7df468138ad8f94d", size = 7001680 } @@ -2585,36 +2525,12 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/aa/ce/c0b912f2f31aeb1b756a6ba56bcd84dd1f8a148470526a48515a3f4d48cd/scikit_learn-1.5.2-cp312-cp312-win_amd64.whl", hash = "sha256:57cc1786cfd6bd118220a92ede80270132aa353647684efa385a74244a41e3b1", size = 10985467 }, ] -[[package]] -name = "scipy" -version = "1.7.3" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.11'", -] -dependencies = [ - { name = "numpy", version = "1.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/61/67/1a654b96309c991762ee9bc39c363fc618076b155fe52d295211cf2536c7/scipy-1.7.3.tar.gz", hash = "sha256:ab5875facfdef77e0a47d5fd39ea178b58e60e454a4c85aa1e52fcb80db7babf", size = 36102562 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4e/88/77ebba491d83a55f0a7d7817cc587c57110e96bc6e55b840e2838293effe/scipy-1.7.3-1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:c9e04d7e9b03a8a6ac2045f7c5ef741be86727d8f49c45db45f244bdd2bcff17", size = 27028448 }, - { url = "https://files.pythonhosted.org/packages/7d/4d/2be384b99480973f8b36a0b5a836a133fca1186acc26eb4c669d948537c3/scipy-1.7.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:173308efba2270dcd61cd45a30dfded6ec0085b4b6eb33b5eb11ab443005e088", size = 33228774 }, - { url = "https://files.pythonhosted.org/packages/0b/8a/a4ec80ca1225c502c85ffb3d96270878f2af7de3589d9b6ddbe5c18fdc53/scipy-1.7.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:21b66200cf44b1c3e86495e3a436fc7a26608f92b8d43d344457c54f1c024cbc", size = 27027301 }, - { url = "https://files.pythonhosted.org/packages/74/59/85b118ea77a1337fd4fad3f4df194c5a6b2e46aa4bcfa8c62a2bf1c8bd43/scipy-1.7.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ceebc3c4f6a109777c0053dfa0282fddb8893eddfb0d598574acfb734a926168", size = 36766069 }, - { url = "https://files.pythonhosted.org/packages/0e/bd/50badd52af542bc9cbad515f55881578a7316dd53914e5993dcf0c70a937/scipy-1.7.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7eaea089345a35130bc9a39b89ec1ff69c208efa97b3f8b25ea5d4c41d88094", size = 39925907 }, - { url = "https://files.pythonhosted.org/packages/52/8a/d53c6a64dd88ef80911a150478367567a9b1254d1926664524867c4d64e2/scipy-1.7.3-cp310-cp310-win_amd64.whl", hash = "sha256:304dfaa7146cffdb75fbf6bb7c190fd7688795389ad060b970269c8576d038e9", size = 34298210 }, -] - [[package]] name = "scipy" version = "1.14.1" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version == '3.11.*'", - "python_full_version >= '3.12'", -] dependencies = [ - { name = "numpy", version = "2.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, ] sdist = { url = "https://files.pythonhosted.org/packages/62/11/4d44a1f274e002784e4dbdb81e0ea96d2de2d1045b2132d5af62cc31fd28/scipy-1.14.1.tar.gz", hash = "sha256:5a275584e726026a5699459aa72f828a610821006228e841b94275c4a7c08417", size = 58620554 } wheels = [ @@ -2650,8 +2566,7 @@ version = "0.13.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "matplotlib" }, - { name = "numpy", version = "1.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, { name = "pandas" }, ] sdist = { url = "https://files.pythonhosted.org/packages/86/59/a451d7420a77ab0b98f7affa3a1d78a313d2f7281a57afb1a34bae8ab412/seaborn-0.13.2.tar.gz", hash = "sha256:93e60a40988f4d65e9f4885df477e2fdaff6b73a9ded434c1ab356dd57eefff7", size = 1457696 } @@ -2741,13 +2656,11 @@ name = "statsmodels" version = "0.13.2" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy", version = "1.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy" }, { name = "packaging" }, { name = "pandas" }, { name = "patsy" }, - { name = "scipy", version = "1.7.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "scipy", version = "1.14.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "scipy" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e1/4a/0eb4efa49cc352e2721e2aebfe8573264db2add195545ec3979c98040c3b/statsmodels-0.13.2.tar.gz", hash = "sha256:77dc292c9939c036a476f1770f9d08976b05437daa229928da73231147cde7d4", size = 17874260 } wheels = [ @@ -2905,7 +2818,7 @@ name = "tqdm" version = "4.66.6" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "colorama", marker = "platform_system == 'Windows'" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/e9/34/bef135b27fe1864993a5284ad001157ee9b5538e859ac90f5b0e8cc8c9ec/tqdm-4.66.6.tar.gz", hash = "sha256:4bdd694238bef1485ce839d67967ab50af8f9272aab687c0d7702a01da0be090", size = 169533 } wheels = [ @@ -2963,14 +2876,11 @@ name = "umap-learn" version = "0.5.7" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numba", version = "0.53.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "numba", version = "0.58.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "1.22.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numba" }, + { name = "numpy" }, { name = "pynndescent" }, { name = "scikit-learn" }, - { name = "scipy", version = "1.7.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "scipy", version = "1.14.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "scipy" }, { name = "tqdm" }, ] sdist = { url = "https://files.pythonhosted.org/packages/6f/d4/9ed627905f7993349671283b3c5bf2d9f543ef79229fa1c7e01324eb900c/umap-learn-0.5.7.tar.gz", hash = "sha256:b2a97973e4c6ffcebf241100a8de589a4c84126a832ab40f296c6d9fcc5eb19e", size = 92680 } From e659eb28a4c2da7e3dedac307acb1e0e63b4503c Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 13:52:21 -0600 Subject: [PATCH 035/265] refactor!: moved `return_placeholder_data` to `como.utils` Signed-off-by: Josh Loecker --- main/COMO.ipynb | 262 +++++++++++++++++++++++++++++++----------- main/como/__init__.py | 11 +- main/como/utils.py | 3 + 3 files changed, 198 insertions(+), 78 deletions(-) diff --git a/main/COMO.ipynb b/main/COMO.ipynb index 3cbebec1..8d79c4be 100644 --- a/main/COMO.ipynb +++ b/main/COMO.ipynb @@ -232,34 +232,42 @@ ] }, { - "metadata": {}, "cell_type": "code", - "outputs": [], - "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2024-12-16T20:09:29.761117Z", + "start_time": "2024-12-16T20:09:29.754605Z" + } + }, "source": [ "from pathlib import Path\n", "\n", "from como.rnaseq_preprocess import rnaseq_preprocess\n", - "from como.types import RNAPrepMethod\n", + "from como.data_types import RNAType\n", "\n", "taxon_id = 9606\n", "context_names = [\"naiveB\"]\n", "\n", - "gene_info_filepath = {context: Path(f\"data/results/{context}/gene_info.csv\") for context in context_names}\n", + "# Input Components\n", "como_context_dir = {context: Path(f\"data/COMO_input/{context}\") for context in context_names}\n", + "gene_info_filepath = {context: Path(f\"data/results/{context}/gene_info.csv\") for context in context_names}\n", "trna_matrix_filepath = {context: Path(f\"data/results/{context}/total-rna/totalrna_{context}.csv\") for context in context_names}\n", - "mrna_matrix_filepath = {context: Path(f\"data/results/{context}/polya-rna/polyarna_{context}.csv\") for context in context_names}\n", + "mrna_matrix_filepath = {context: Path(f\"data/results/{context}/mrna/mrna_{context}.csv\") for context in context_names}\n", "proteomics_matrix_filepath = {context: Path(f\"data/data_matrices/{context}/protein_abundance_{context}.csv\") for context in context_names}\n", "\n", + "# No single-cell data is provided by default; COMO accepts single-cell data in CSV or h5ad format\n", + "# If you are using single-cell data, adjust the following lines accordingly\n", + "scrna_matrix_filepath = {context: Path(f\"data/results/{context}/scrna/scrna_{context}.csv\") for context in context_names}\n", + "# scrna_matrix_filepath = [Path(f\"data/results/{context}/scrna/scrna_{context}.h5ad\") for context in context_names]\n", + "\n", "trna_metadata_filepath = Path(\"data/config_sheets/trna_config.xlsx\")\n", "mrna_metadata_filepath = Path(\"data/config_sheets/mrna_config.xlsx\")\n", "proteomics_metadata_filepath = Path(\"data/config_sheets/proteomics_config.xlsx\")\n", "\n", - "# No single-cell data is provided by default; COMO accepts single-cell data in CSV or h5ad format\n", - "# If you are using single-cell data, adjust the following lines accordingly\n", - "scrna_matrix_filepath = {context: Path(f\"data/results/{context}/scrna/scrna_{context}.csv\") for context in context_names}\n", - "# scrna_matrix_filepath = [Path(f\"data/results/{context}/scrna/scrna_{context}.h5ad\") for context in context_names]\n" - ] + "# Output Components\n" + ], + "outputs": [], + "execution_count": 11 }, { "cell_type": "markdown", @@ -273,10 +281,13 @@ ] }, { - "metadata": {}, "cell_type": "code", - "outputs": [], - "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2024-12-16T20:07:08.331063Z", + "start_time": "2024-12-16T20:06:10.188429Z" + } + }, "source": [ "for context in context_names:\n", " if context not in {*trna_matrix_filepath, *mrna_matrix_filepath}:\n", @@ -287,14 +298,27 @@ " como_context_dir=como_context_dir[context],\n", " input_matrix_filepath=None,\n", " output_gene_info_filepath=gene_info_filepath[context],\n", - " output_trna_config_filepath=trna_metadata_filepath,\n", + " output_trna_metadata_filepath=trna_metadata_filepath,\n", " output_trna_count_matrix_filepath=trna_matrix_filepath[context],\n", - " output_mrna_config_filepath=mrna_metadata_filepath,\n", + " output_mrna_metadata_filepath=mrna_metadata_filepath,\n", " output_mrna_count_matrix_filepath=mrna_matrix_filepath[context],\n", " cache=True,\n", " log_level=\"INFO\",\n", " )" - ] + ], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\u001B[32m2024-12-16 14:06:13\u001B[0m | \u001B[32m\u001B[1mSUCCESS \u001B[0m | \u001B[36mcomo.rnaseq_preprocess\u001B[0m:\u001B[36m277\u001B[0m - \u001B[32m\u001B[1mWrote gene count matrix for 'mrna' RNA at '/Users/joshl/Projects/COMO/main/data/results/naiveB/polya-rna/polyarna_naiveB.csv'\u001B[0m\n", + "\u001B[32m2024-12-16 14:06:13\u001B[0m | \u001B[32m\u001B[1mSUCCESS \u001B[0m | \u001B[36mcomo.rnaseq_preprocess\u001B[0m:\u001B[36m277\u001B[0m - \u001B[32m\u001B[1mWrote gene count matrix for 'total' RNA at '/Users/joshl/Projects/COMO/main/data/results/naiveB/total-rna/totalrna_naiveB.csv'\u001B[0m\n", + "\u001B[32m2024-12-16 14:06:13\u001B[0m | \u001B[1mINFO \u001B[0m | \u001B[36mcomo.rnaseq_preprocess\u001B[0m:\u001B[36m468\u001B[0m - \u001B[1mFetching gene info (this may take 1-5 minutes depending on the number of genes and your internet connection)\u001B[0m\n", + "\u001B[32m2024-12-16 14:07:08\u001B[0m | \u001B[32m\u001B[1mSUCCESS \u001B[0m | \u001B[36mcomo.rnaseq_preprocess\u001B[0m:\u001B[36m505\u001B[0m - \u001B[32m\u001B[1mGene Info file written at '/Users/joshl/Projects/COMO/main/data/results/naiveB/gene_info.csv'\u001B[0m\n" + ] + } + ], + "execution_count": 8 }, { "cell_type": "markdown", @@ -367,10 +391,13 @@ ] }, { - "metadata": {}, "cell_type": "code", - "outputs": [], - "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2024-12-16T20:08:00.274368Z", + "start_time": "2024-12-16T20:07:48.637980Z" + } + }, "source": [ "from como.rnaseq_gen import FilteringTechnique, rnaseq_gen\n", "\n", @@ -378,9 +405,10 @@ "high_confidence_replicate_ratio = 1.0\n", "batch_ratio = 0.75\n", "high_confidence_batch_ratio = 1.0\n", - "technique = FilteringTechnique.zfpkm\n", + "technique = FilteringTechnique.ZFPKM\n", "cutoff = -3\n", "\n", + "\n", "for context in context_names:\n", " if context not in trna_matrix_filepath:\n", " continue\n", @@ -388,9 +416,9 @@ " context_name=context,\n", " input_rnaseq_filepath=trna_matrix_filepath[context],\n", " input_gene_info_filepath=gene_info_filepath[context],\n", - " output_rnaseq_filepath=trna_matrix_filepath[context],\n", - " prep=RNAPrepMethod.TOTAL,\n", - " taxon=taxon_id,\n", + " output_boolean_activity_filepath=trna_matrix_filepath[context],\n", + " prep=RNAType.TRNA,\n", + " taxon_id=taxon_id,\n", " input_metadata_filepath=trna_metadata_filepath,\n", " replicate_ratio=replicate_ratio,\n", " high_replicate_ratio=high_confidence_replicate_ratio,\n", @@ -399,7 +427,20 @@ " technique=technique,\n", " cutoff=cutoff\n", " )" - ] + ], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/joshl/Projects/COMO/main/como/rnaseq_gen.py:430: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n", + " mega_df = pd.concat([mega_df, df], ignore_index=True)\n", + "\u001B[32m2024-12-16 14:08:00\u001B[0m | \u001B[1mINFO \u001B[0m | \u001B[36mcomo.rnaseq_gen\u001B[0m:\u001B[36m691\u001B[0m - \u001B[1mnaiveB - Found 9492 expressed and 9492 confidently expressed genes\u001B[0m\n", + "\u001B[32m2024-12-16 14:08:00\u001B[0m | \u001B[32m\u001B[1mSUCCESS \u001B[0m | \u001B[36mcomo.rnaseq_gen\u001B[0m:\u001B[36m694\u001B[0m - \u001B[32m\u001B[1mWrote boolean matrix to data/results/naiveB/total-rna/totalrna_naiveB.csv\u001B[0m\n" + ] + } + ], + "execution_count": 9 }, { "cell_type": "markdown", @@ -421,10 +462,13 @@ ] }, { - "metadata": {}, "cell_type": "code", - "outputs": [], - "execution_count": null, + "metadata": { + "ExecuteTime": { + "end_time": "2024-12-16T20:15:16.139743Z", + "start_time": "2024-12-16T20:15:15.998158Z" + } + }, "source": [ "from como.rnaseq_gen import FilteringTechnique, rnaseq_gen\n", "\n", @@ -432,7 +476,7 @@ "high_confidence_replicate_ratio = 1.0\n", "batch_ratio = 0.75\n", "high_confidence_batch_ratio = 1.0\n", - "technique = FilteringTechnique.zfpkm\n", + "technique = FilteringTechnique.ZFPKM\n", "cutoff = -3\n", "\n", "for context in context_names:\n", @@ -442,9 +486,9 @@ " context_name=context,\n", " input_rnaseq_filepath=mrna_matrix_filepath[context],\n", " input_gene_info_filepath=gene_info_filepath[context],\n", - " output_rnaseq_filepath=mrna_matrix_filepath[context],\n", - " prep=RNAPrepMethod.MRNA,\n", - " taxon=taxon_id,\n", + " output_boolean_activity_filepath=mrna_matrix_filepath[context],\n", + " prep=RNAType.MRNA,\n", + " taxon_id=taxon_id,\n", " input_metadata_filepath=mrna_metadata_filepath,\n", " replicate_ratio=replicate_ratio,\n", " high_replicate_ratio=high_confidence_replicate_ratio,\n", @@ -453,7 +497,34 @@ " technique=technique,\n", " cutoff=cutoff\n", " )" - ] + ], + "outputs": [ + { + "ename": "KeyError", + "evalue": "'ensembl_gene_id'", + "output_type": "error", + "traceback": [ + "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", + "\u001B[0;31mKeyError\u001B[0m Traceback (most recent call last)", + "File \u001B[0;32m~/Projects/COMO/.venv/lib/python3.10/site-packages/pandas/core/indexes/base.py:3805\u001B[0m, in \u001B[0;36mIndex.get_loc\u001B[0;34m(self, key)\u001B[0m\n\u001B[1;32m 3804\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[0;32m-> 3805\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_engine\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mget_loc\u001B[49m\u001B[43m(\u001B[49m\u001B[43mcasted_key\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 3806\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mKeyError\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m err:\n", + "File \u001B[0;32mindex.pyx:167\u001B[0m, in \u001B[0;36mpandas._libs.index.IndexEngine.get_loc\u001B[0;34m()\u001B[0m\n", + "File \u001B[0;32mindex.pyx:196\u001B[0m, in \u001B[0;36mpandas._libs.index.IndexEngine.get_loc\u001B[0;34m()\u001B[0m\n", + "File \u001B[0;32mpandas/_libs/hashtable_class_helper.pxi:7081\u001B[0m, in \u001B[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001B[0;34m()\u001B[0m\n", + "File \u001B[0;32mpandas/_libs/hashtable_class_helper.pxi:7089\u001B[0m, in \u001B[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001B[0;34m()\u001B[0m\n", + "\u001B[0;31mKeyError\u001B[0m: 'ensembl_gene_id'", + "\nThe above exception was the direct cause of the following exception:\n", + "\u001B[0;31mKeyError\u001B[0m Traceback (most recent call last)", + "Cell \u001B[0;32mIn[15], line 13\u001B[0m\n\u001B[1;32m 11\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m context \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;129;01min\u001B[39;00m mrna_matrix_filepath:\n\u001B[1;32m 12\u001B[0m \u001B[38;5;28;01mcontinue\u001B[39;00m\n\u001B[0;32m---> 13\u001B[0m \u001B[38;5;28;01mawait\u001B[39;00m rnaseq_gen(\n\u001B[1;32m 14\u001B[0m context_name\u001B[38;5;241m=\u001B[39mcontext,\n\u001B[1;32m 15\u001B[0m input_rnaseq_filepath\u001B[38;5;241m=\u001B[39mmrna_matrix_filepath[context],\n\u001B[1;32m 16\u001B[0m input_gene_info_filepath\u001B[38;5;241m=\u001B[39mgene_info_filepath[context],\n\u001B[1;32m 17\u001B[0m output_rnaseq_filepath\u001B[38;5;241m=\u001B[39mmrna_matrix_filepath[context],\n\u001B[1;32m 18\u001B[0m prep\u001B[38;5;241m=\u001B[39mRNAPrepMethod\u001B[38;5;241m.\u001B[39mMRNA,\n\u001B[1;32m 19\u001B[0m taxon\u001B[38;5;241m=\u001B[39mtaxon_id,\n\u001B[1;32m 20\u001B[0m input_metadata_filepath\u001B[38;5;241m=\u001B[39mmrna_metadata_filepath,\n\u001B[1;32m 21\u001B[0m replicate_ratio\u001B[38;5;241m=\u001B[39mreplicate_ratio,\n\u001B[1;32m 22\u001B[0m high_replicate_ratio\u001B[38;5;241m=\u001B[39mhigh_confidence_replicate_ratio,\n\u001B[1;32m 23\u001B[0m batch_ratio\u001B[38;5;241m=\u001B[39mbatch_ratio,\n\u001B[1;32m 24\u001B[0m high_batch_ratio\u001B[38;5;241m=\u001B[39mhigh_confidence_batch_ratio,\n\u001B[1;32m 25\u001B[0m technique\u001B[38;5;241m=\u001B[39mtechnique,\n\u001B[1;32m 26\u001B[0m cutoff\u001B[38;5;241m=\u001B[39mcutoff\n\u001B[1;32m 27\u001B[0m )\n", + "File \u001B[0;32m~/Projects/COMO/main/como/rnaseq_gen.py:787\u001B[0m, in \u001B[0;36mrnaseq_gen\u001B[0;34m(context_name, input_rnaseq_filepath, input_gene_info_filepath, output_rnaseq_filepath, prep, taxon, input_metadata_filepath, input_metadata_df, replicate_ratio, high_replicate_ratio, batch_ratio, high_batch_ratio, technique, cutoff)\u001B[0m\n\u001B[1;32m 784\u001B[0m logger\u001B[38;5;241m.\u001B[39mdebug(\u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mStarting \u001B[39m\u001B[38;5;124m'\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext_name\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m'\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n\u001B[1;32m 785\u001B[0m output_rnaseq_filepath\u001B[38;5;241m.\u001B[39mparent\u001B[38;5;241m.\u001B[39mmkdir(parents\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mTrue\u001B[39;00m, exist_ok\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mTrue\u001B[39;00m)\n\u001B[0;32m--> 787\u001B[0m \u001B[38;5;28;01mawait\u001B[39;00m _save_rnaseq_tests(\n\u001B[1;32m 788\u001B[0m context_name\u001B[38;5;241m=\u001B[39mcontext_name,\n\u001B[1;32m 789\u001B[0m rnaseq_matrix\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mawait\u001B[39;00m _read_counts(input_rnaseq_filepath),\n\u001B[1;32m 790\u001B[0m metadata_df\u001B[38;5;241m=\u001B[39minput_metadata_df \u001B[38;5;129;01mor\u001B[39;00m \u001B[38;5;28;01mawait\u001B[39;00m _create_metadata_df(input_metadata_filepath),\n\u001B[1;32m 791\u001B[0m gene_info_df\u001B[38;5;241m=\u001B[39mpd\u001B[38;5;241m.\u001B[39mread_csv(input_gene_info_filepath),\n\u001B[1;32m 792\u001B[0m output_filepath\u001B[38;5;241m=\u001B[39moutput_rnaseq_filepath,\n\u001B[1;32m 793\u001B[0m prep\u001B[38;5;241m=\u001B[39mprep,\n\u001B[1;32m 794\u001B[0m taxon\u001B[38;5;241m=\u001B[39mtaxon,\n\u001B[1;32m 795\u001B[0m replicate_ratio\u001B[38;5;241m=\u001B[39mreplicate_ratio,\n\u001B[1;32m 796\u001B[0m batch_ratio\u001B[38;5;241m=\u001B[39mbatch_ratio,\n\u001B[1;32m 797\u001B[0m high_replicate_ratio\u001B[38;5;241m=\u001B[39mhigh_replicate_ratio,\n\u001B[1;32m 798\u001B[0m high_batch_ratio\u001B[38;5;241m=\u001B[39mhigh_batch_ratio,\n\u001B[1;32m 799\u001B[0m technique\u001B[38;5;241m=\u001B[39mtechnique,\n\u001B[1;32m 800\u001B[0m cut_off\u001B[38;5;241m=\u001B[39mcutoff,\n\u001B[1;32m 801\u001B[0m )\n", + "File \u001B[0;32m~/Projects/COMO/main/como/rnaseq_gen.py:645\u001B[0m, in \u001B[0;36m_save_rnaseq_tests\u001B[0;34m(context_name, rnaseq_matrix, metadata_df, gene_info_df, output_filepath, prep, taxon, replicate_ratio, batch_ratio, high_replicate_ratio, high_batch_ratio, technique, cut_off)\u001B[0m\n\u001B[1;32m 636\u001B[0m \u001B[38;5;250m\u001B[39m\u001B[38;5;124;03m\"\"\"Save the results of the RNA-Seq tests to a CSV file.\"\"\"\u001B[39;00m\n\u001B[1;32m 637\u001B[0m filtering_options \u001B[38;5;241m=\u001B[39m _FilteringOptions(\n\u001B[1;32m 638\u001B[0m replicate_ratio\u001B[38;5;241m=\u001B[39mreplicate_ratio,\n\u001B[1;32m 639\u001B[0m batch_ratio\u001B[38;5;241m=\u001B[39mbatch_ratio,\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 642\u001B[0m high_batch_ratio\u001B[38;5;241m=\u001B[39mhigh_batch_ratio,\n\u001B[1;32m 643\u001B[0m )\n\u001B[0;32m--> 645\u001B[0m read_counts_results: _ReadMatrixResults \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mawait\u001B[39;00m _build_matrix_results(\n\u001B[1;32m 646\u001B[0m matrix\u001B[38;5;241m=\u001B[39mrnaseq_matrix,\n\u001B[1;32m 647\u001B[0m gene_info\u001B[38;5;241m=\u001B[39mgene_info_df,\n\u001B[1;32m 648\u001B[0m metadata_df\u001B[38;5;241m=\u001B[39mmetadata_df,\n\u001B[1;32m 649\u001B[0m taxon\u001B[38;5;241m=\u001B[39mtaxon,\n\u001B[1;32m 650\u001B[0m )\n\u001B[1;32m 651\u001B[0m metrics \u001B[38;5;241m=\u001B[39m read_counts_results\u001B[38;5;241m.\u001B[39mmetrics\n\u001B[1;32m 652\u001B[0m entrez_gene_ids \u001B[38;5;241m=\u001B[39m read_counts_results\u001B[38;5;241m.\u001B[39mentrez_gene_ids\n", + "File \u001B[0;32m~/Projects/COMO/main/como/rnaseq_gen.py:175\u001B[0m, in \u001B[0;36m_build_matrix_results\u001B[0;34m(matrix, gene_info, metadata_df, taxon)\u001B[0m\n\u001B[1;32m 167\u001B[0m \u001B[38;5;250m\u001B[39m\u001B[38;5;124;03m\"\"\"Read the counts matrix and returns the results.\u001B[39;00m\n\u001B[1;32m 168\u001B[0m \n\u001B[1;32m 169\u001B[0m \u001B[38;5;124;03m:param matrix: The gene counts matrix to process\u001B[39;00m\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 172\u001B[0m \u001B[38;5;124;03m:return: A dataclass `ReadMatrixResults`\u001B[39;00m\n\u001B[1;32m 173\u001B[0m \u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[1;32m 174\u001B[0m gene_info \u001B[38;5;241m=\u001B[39m gene_info_migrations(gene_info)\n\u001B[0;32m--> 175\u001B[0m conversion \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mawait\u001B[39;00m ensembl_to_gene_id_and_symbol(ids\u001B[38;5;241m=\u001B[39m\u001B[43mmatrix\u001B[49m\u001B[43m[\u001B[49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43mensembl_gene_id\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[43m]\u001B[49m\u001B[38;5;241m.\u001B[39mtolist(), taxon\u001B[38;5;241m=\u001B[39mtaxon)\n\u001B[1;32m 176\u001B[0m matrix \u001B[38;5;241m=\u001B[39m matrix\u001B[38;5;241m.\u001B[39mmerge(conversion, on\u001B[38;5;241m=\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mensembl_gene_id\u001B[39m\u001B[38;5;124m\"\u001B[39m, how\u001B[38;5;241m=\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mleft\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n\u001B[1;32m 178\u001B[0m \u001B[38;5;66;03m# Only include Entrez and Ensembl Gene IDs that are present in `gene_info`\u001B[39;00m\n", + "File \u001B[0;32m~/Projects/COMO/.venv/lib/python3.10/site-packages/pandas/core/frame.py:4102\u001B[0m, in \u001B[0;36mDataFrame.__getitem__\u001B[0;34m(self, key)\u001B[0m\n\u001B[1;32m 4100\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mcolumns\u001B[38;5;241m.\u001B[39mnlevels \u001B[38;5;241m>\u001B[39m \u001B[38;5;241m1\u001B[39m:\n\u001B[1;32m 4101\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_getitem_multilevel(key)\n\u001B[0;32m-> 4102\u001B[0m indexer \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mcolumns\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mget_loc\u001B[49m\u001B[43m(\u001B[49m\u001B[43mkey\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 4103\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m is_integer(indexer):\n\u001B[1;32m 4104\u001B[0m indexer \u001B[38;5;241m=\u001B[39m [indexer]\n", + "File \u001B[0;32m~/Projects/COMO/.venv/lib/python3.10/site-packages/pandas/core/indexes/base.py:3812\u001B[0m, in \u001B[0;36mIndex.get_loc\u001B[0;34m(self, key)\u001B[0m\n\u001B[1;32m 3807\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(casted_key, \u001B[38;5;28mslice\u001B[39m) \u001B[38;5;129;01mor\u001B[39;00m (\n\u001B[1;32m 3808\u001B[0m \u001B[38;5;28misinstance\u001B[39m(casted_key, abc\u001B[38;5;241m.\u001B[39mIterable)\n\u001B[1;32m 3809\u001B[0m \u001B[38;5;129;01mand\u001B[39;00m \u001B[38;5;28many\u001B[39m(\u001B[38;5;28misinstance\u001B[39m(x, \u001B[38;5;28mslice\u001B[39m) \u001B[38;5;28;01mfor\u001B[39;00m x \u001B[38;5;129;01min\u001B[39;00m casted_key)\n\u001B[1;32m 3810\u001B[0m ):\n\u001B[1;32m 3811\u001B[0m \u001B[38;5;28;01mraise\u001B[39;00m InvalidIndexError(key)\n\u001B[0;32m-> 3812\u001B[0m \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mKeyError\u001B[39;00m(key) \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01merr\u001B[39;00m\n\u001B[1;32m 3813\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mTypeError\u001B[39;00m:\n\u001B[1;32m 3814\u001B[0m \u001B[38;5;66;03m# If we have a listlike key, _check_indexing_error will raise\u001B[39;00m\n\u001B[1;32m 3815\u001B[0m \u001B[38;5;66;03m# InvalidIndexError. Otherwise we fall through and re-raise\u001B[39;00m\n\u001B[1;32m 3816\u001B[0m \u001B[38;5;66;03m# the TypeError.\u001B[39;00m\n\u001B[1;32m 3817\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_check_indexing_error(key)\n", + "\u001B[0;31mKeyError\u001B[0m: 'ensembl_gene_id'" + ] + } + ], + "execution_count": 15 }, { "cell_type": "markdown", @@ -475,10 +546,10 @@ ] }, { - "metadata": {}, "cell_type": "code", - "outputs": [], "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "from como.rnaseq_gen import FilteringTechnique, rnaseq_gen\n", "\n", @@ -486,7 +557,7 @@ "high_confidence_replicate_ratio = 1.0\n", "batch_ratio = 0.75\n", "high_confidence_batch_ratio = 1.0\n", - "technique = FilteringTechnique.umi\n", + "technique = FilteringTechnique.UMI\n", "cutoff = -3\n", "\n", "for context in context_names:\n", @@ -496,9 +567,9 @@ " context_name=context,\n", " input_rnaseq_filepath=scrna_matrix_filepath[context],\n", " input_gene_info_filepath=gene_info_filepath[context],\n", - " output_rnaseq_filepath=scrna_matrix_filepath[context],\n", - " prep=RNAPrepMethod.SCRNA,\n", - " taxon=taxon_id,\n", + " output_boolean_activity_filepath=scrna_matrix_filepath[context],\n", + " prep=RNAType.SCRNA,\n", + " taxon_id=taxon_id,\n", " input_metadata_filepath=Path(\"./data/config_sheets/scrna_config.xlsx\"),\n", " replicate_ratio=replicate_ratio,\n", " high_replicate_ratio=high_confidence_replicate_ratio,\n", @@ -526,10 +597,10 @@ ] }, { - "metadata": {}, "cell_type": "code", - "outputs": [], "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "from como.proteomics_gen import proteomics_gen\n", "\n", @@ -552,8 +623,8 @@ ] }, { - "metadata": {}, "cell_type": "markdown", + "metadata": {}, "source": [ "# Cluster Sample Data (Optional)\n", "This step is used to cluster the samples based on their expression values. This can be used to determine which samples are more similar to each other. In a perfect world, one cluster would be created for each context type used. This is done using the `como/cluster_rnaseq.py` script.\n", @@ -577,10 +648,10 @@ ] }, { - "metadata": {}, "cell_type": "code", - "outputs": [], "execution_count": null, + "metadata": {}, + "outputs": [], "source": [ "filt_technique = \"zfpkm\"\n", "cluster_algorithm = \"umap\"\n", @@ -660,39 +731,90 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "metadata": { + "ExecuteTime": { + "end_time": "2024-12-16T19:54:26.540397Z", + "start_time": "2024-12-16T19:54:26.515554Z" + } + }, "source": [ - "expression_requirement = 3\n", - "requirement_adjust = \"regressive\"\n", + "from como.merge_xomics import merge_xomics, AdjustmentMethod\n", + "\n", "total_rna_weight = 6\n", "mrna_weight = 6\n", "single_cell_weight = 6\n", "proteomics_weight = 10\n", + "minimum_source_expression = 1\n", + "expression_requirement = 1\n", + "requirement_adjustment_method = AdjustmentMethod.REGRESSIVE\n", + "force_activate_high_confidence = False\n", + "adjust_for_na_sources = False\n", + "merge_zfpkm_distrubution = True\n", + "keep_transcriptomics_score = True\n", "\n", - "# fmt: off\n", - "cmd = \" \".join(\n", - " [\n", - " \"python3\", \"como/merge_xomics.py\",\n", - " \"--merge-zfpkm-distribution\",\n", - " \"--total-rnaseq-config-file\", trnaseq_config_file, # noqa: F821\n", - " \"--mrnaseq-config-file\", mrnaseq_config_file, # noqa: F821\n", - " # \"--scrnaseq-config-file\", scrnaseq_config_file, # If using single-cell data, uncomment the start of this line\n", - " # \"--proteomics-config-file\", proteomics_config_file, # If using proteomics data, uncomment the start of this line\n", - " \"--requirement-adjust\", requirement_adjust,\n", - " \"--expression-requirement\", str(expression_requirement),\n", - " \"--total-rnaseq-weight\", str(total_rna_weight),\n", - " \"--mrnaseq-weight\", str(mrna_weight),\n", - " \"--single-cell-rnaseq-weight\", str(single_cell_weight),\n", - " \"--protein-weight\", str(proteomics_weight),\n", - " \"--no-high-confidence\",\n", - " ]\n", - ")\n", - "# fmt: on\n", "\n", - "!{cmd}" - ] + "mrna_batches = {\"naiveB\": [\n", + " \"naiveB_S1R1\", \"naiveB_S1R2\", \"naiveB_S1R3\", \"naiveB_S1R4\",\n", + " \"naiveB_S2R1\", \"naiveB_S2R2\", \"naiveB_S2R3\", \"naiveB_S2R4\",\n", + "]}\n", + "trna_batches = {\"naiveB\": [\"naiveB_S3R1\", \"naiveB_S3R2\", \"naiveB_S3R3\"]}\n", + "\n", + "\n", + "for context in context_names:\n", + " await merge_xomics(\n", + " context_name=context,\n", + " trna_matrix_or_filepath=trna_matrix_filepath[context],\n", + " mrna_matrix_or_filepath=mrna_matrix_filepath[context],\n", + " scrna_matrix_or_filepath=None, # scrna_matrix_filepath[context],\n", + " proteomic_matrix_or_filepath=None, # proteomics_matrix_filepath[context],\n", + " trna_batches=trna_batches,\n", + " mrna_batches=mrna_batches,\n", + " scrna_batches=None,\n", + " proteomic_batches=None,\n", + " trna_weight=total_rna_weight,\n", + " mrna_weight=mrna_weight,\n", + " scrna_weight=single_cell_weight,\n", + " proteomic_weight=proteomics_weight,\n", + " minimum_source_expression=minimum_source_expression,\n", + " expression_requirement=expression_requirement,\n", + " adjust_method=requirement_adjustment_method,\n", + " force_activate_high_confidence=force_activate_high_confidence,\n", + " adjust_for_na=adjust_for_na_sources,\n", + " merge_zfpkm_distribution=merge_zfpkm_distrubution,\n", + " keep_transcriptomics_score=keep_transcriptomics_score,\n", + " output_merge_activity_filepath=Path(f\"data/results/{context}/ActiveGenes_{context}_Merged.csv\"),\n", + " output_transcriptomic_details_filepath=Path(f\"data/results/{context}/TranscriptomicDetails_{context}.csv\"),\n", + " output_trna_activity_filepath=Path(f\"data/results/{context}/total-rna/trna_activity_{context}.csv\"),\n", + " output_mrna_activity_filepath=Path(f\"data/results/{context}/mrna/mrna_activity_{context}.csv\"),\n", + " output_scrna_activity_filepath=Path(f\"data/results/{context}/scrna/scrna_activity_{context}.csv\"),\n", + " output_proteomic_activity_filepath=Path(f\"data/results/{context}/proteomics/proteomic_activity_{context}.csv\"),\n", + " output_final_model_scores_filepath=Path(f\"data/results/{context}/model_scores_{context}.csv\"),\n", + " output_figure_dirpath=Path(f\"data/results/{context}/figures\")\n", + " )" + ], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "data/results/naiveB/total-rna/trna_activity_naiveB.csv\n" + ] + }, + { + "ename": "FileExistsError", + "evalue": "[Errno 17] File exists: 'data/results/naiveB/total-rna'", + "output_type": "error", + "traceback": [ + "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", + "\u001B[0;31mFileExistsError\u001B[0m Traceback (most recent call last)", + "Cell \u001B[0;32mIn[6], line 24\u001B[0m\n\u001B[1;32m 20\u001B[0m trna_batches \u001B[38;5;241m=\u001B[39m {\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mnaiveB\u001B[39m\u001B[38;5;124m\"\u001B[39m: [\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mnaiveB_S3R1\u001B[39m\u001B[38;5;124m\"\u001B[39m, \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mnaiveB_S3R2\u001B[39m\u001B[38;5;124m\"\u001B[39m, \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mnaiveB_S3R3\u001B[39m\u001B[38;5;124m\"\u001B[39m]}\n\u001B[1;32m 23\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m context \u001B[38;5;129;01min\u001B[39;00m context_names:\n\u001B[0;32m---> 24\u001B[0m \u001B[38;5;28;01mawait\u001B[39;00m merge_xomics(\n\u001B[1;32m 25\u001B[0m context_name\u001B[38;5;241m=\u001B[39mcontext_names,\n\u001B[1;32m 26\u001B[0m trna_matrix_or_filepath\u001B[38;5;241m=\u001B[39mtrna_matrix_filepath[context],\n\u001B[1;32m 27\u001B[0m mrna_matrix_or_filepath\u001B[38;5;241m=\u001B[39mmrna_matrix_filepath[context],\n\u001B[1;32m 28\u001B[0m scrna_matrix_or_filepath\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mNone\u001B[39;00m, \u001B[38;5;66;03m# scrna_matrix_filepath[context],\u001B[39;00m\n\u001B[1;32m 29\u001B[0m proteomic_matrix_or_filepath\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mNone\u001B[39;00m, \u001B[38;5;66;03m# proteomics_matrix_filepath[context],\u001B[39;00m\n\u001B[1;32m 30\u001B[0m trna_batches\u001B[38;5;241m=\u001B[39mtrna_batches,\n\u001B[1;32m 31\u001B[0m mrna_batches\u001B[38;5;241m=\u001B[39mmrna_batches,\n\u001B[1;32m 32\u001B[0m scrna_batches\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mNone\u001B[39;00m,\n\u001B[1;32m 33\u001B[0m proteomic_batches\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mNone\u001B[39;00m,\n\u001B[1;32m 34\u001B[0m trna_weight\u001B[38;5;241m=\u001B[39mtotal_rna_weight,\n\u001B[1;32m 35\u001B[0m mrna_weight\u001B[38;5;241m=\u001B[39mmrna_weight,\n\u001B[1;32m 36\u001B[0m scrna_weight\u001B[38;5;241m=\u001B[39msingle_cell_weight,\n\u001B[1;32m 37\u001B[0m proteomic_weight\u001B[38;5;241m=\u001B[39mproteomics_weight,\n\u001B[1;32m 38\u001B[0m minimum_source_expression\u001B[38;5;241m=\u001B[39mminimum_source_expression,\n\u001B[1;32m 39\u001B[0m expression_requirement\u001B[38;5;241m=\u001B[39mexpression_requirement,\n\u001B[1;32m 40\u001B[0m adjust_method\u001B[38;5;241m=\u001B[39mrequirement_adjustment_method,\n\u001B[1;32m 41\u001B[0m force_activate_high_confidence\u001B[38;5;241m=\u001B[39mforce_activate_high_confidence,\n\u001B[1;32m 42\u001B[0m adjust_for_na\u001B[38;5;241m=\u001B[39madjust_for_na_sources,\n\u001B[1;32m 43\u001B[0m merge_zfpkm_distribution\u001B[38;5;241m=\u001B[39mmerge_zfpkm_distrubution,\n\u001B[1;32m 44\u001B[0m keep_transcriptomics_score\u001B[38;5;241m=\u001B[39mkeep_transcriptomics_score,\n\u001B[1;32m 45\u001B[0m output_merge_activity_filepath\u001B[38;5;241m=\u001B[39mPath(\u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mdata/results/\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m/ActiveGenes_\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m_Merged.csv\u001B[39m\u001B[38;5;124m\"\u001B[39m),\n\u001B[1;32m 46\u001B[0m output_transcriptomic_details_filepath\u001B[38;5;241m=\u001B[39mPath(\u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mdata/results/\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m/TranscriptomicDetails_\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m.csv\u001B[39m\u001B[38;5;124m\"\u001B[39m),\n\u001B[1;32m 47\u001B[0m output_trna_activity_filepath\u001B[38;5;241m=\u001B[39mPath(\u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mdata/results/\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m/total-rna/trna_activity_\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m.csv\u001B[39m\u001B[38;5;124m\"\u001B[39m),\n\u001B[1;32m 48\u001B[0m output_mrna_activity_filepath\u001B[38;5;241m=\u001B[39mPath(\u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mdata/results/\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m/mrna/mrna_activity_\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m.csv\u001B[39m\u001B[38;5;124m\"\u001B[39m),\n\u001B[1;32m 49\u001B[0m output_scrna_activity_filepath\u001B[38;5;241m=\u001B[39mPath(\u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mdata/results/\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m/scrna/scrna_activity_\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m.csv\u001B[39m\u001B[38;5;124m\"\u001B[39m),\n\u001B[1;32m 50\u001B[0m output_proteomic_activity_filepath\u001B[38;5;241m=\u001B[39mPath(\u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mdata/results/\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m/proteomics/proteomic_activity_\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m.csv\u001B[39m\u001B[38;5;124m\"\u001B[39m),\n\u001B[1;32m 51\u001B[0m output_final_model_scores_filepath\u001B[38;5;241m=\u001B[39mPath(\u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mdata/results/\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m/model_scores_\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m.csv\u001B[39m\u001B[38;5;124m\"\u001B[39m),\n\u001B[1;32m 52\u001B[0m output_figure_dirpath\u001B[38;5;241m=\u001B[39mPath(\u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mdata/results/\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m/figures\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n\u001B[1;32m 53\u001B[0m )\n", + "File \u001B[0;32m~/Projects/COMO/main/como/merge_xomics.py:678\u001B[0m, in \u001B[0;36mmerge_xomics\u001B[0;34m(context_name, trna_matrix_or_filepath, mrna_matrix_or_filepath, scrna_matrix_or_filepath, proteomic_matrix_or_filepath, trna_batches, mrna_batches, scrna_batches, proteomic_batches, output_merge_activity_filepath, output_transcriptomic_details_filepath, output_trna_activity_filepath, output_mrna_activity_filepath, output_scrna_activity_filepath, output_proteomic_activity_filepath, output_final_model_scores_filepath, output_figure_dirpath, trna_weight, mrna_weight, scrna_weight, proteomic_weight, minimum_source_expression, expression_requirement, adjust_method, force_activate_high_confidence, adjust_for_na, merge_zfpkm_distribution, keep_transcriptomics_score, weighted_z_floor, weighted_z_ceiling)\u001B[0m\n\u001B[1;32m 676\u001B[0m output_transcriptomic_details_filepath\u001B[38;5;241m.\u001B[39mparent\u001B[38;5;241m.\u001B[39mmkdir(parents\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mTrue\u001B[39;00m)\n\u001B[1;32m 677\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m output_trna_activity_filepath \u001B[38;5;129;01mand\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m output_trna_activity_filepath\u001B[38;5;241m.\u001B[39mexists():\n\u001B[0;32m--> 678\u001B[0m \u001B[43moutput_trna_activity_filepath\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mparent\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mmkdir\u001B[49m\u001B[43m(\u001B[49m\u001B[43mparents\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;28;43;01mTrue\u001B[39;49;00m\u001B[43m)\u001B[49m\n\u001B[1;32m 679\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m output_mrna_activity_filepath \u001B[38;5;129;01mand\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m output_mrna_activity_filepath\u001B[38;5;241m.\u001B[39mexists():\n\u001B[1;32m 680\u001B[0m output_mrna_activity_filepath\u001B[38;5;241m.\u001B[39mparent\u001B[38;5;241m.\u001B[39mmkdir(parents\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mTrue\u001B[39;00m)\n", + "File \u001B[0;32m~/.local/share/uv/python/cpython-3.10.15-macos-aarch64-none/lib/python3.10/pathlib.py:1175\u001B[0m, in \u001B[0;36mPath.mkdir\u001B[0;34m(self, mode, parents, exist_ok)\u001B[0m\n\u001B[1;32m 1171\u001B[0m \u001B[38;5;250m\u001B[39m\u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[1;32m 1172\u001B[0m \u001B[38;5;124;03mCreate a new directory at this given path.\u001B[39;00m\n\u001B[1;32m 1173\u001B[0m \u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[1;32m 1174\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[0;32m-> 1175\u001B[0m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_accessor\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mmkdir\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmode\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 1176\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mFileNotFoundError\u001B[39;00m:\n\u001B[1;32m 1177\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m parents \u001B[38;5;129;01mor\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mparent \u001B[38;5;241m==\u001B[39m \u001B[38;5;28mself\u001B[39m:\n", + "\u001B[0;31mFileExistsError\u001B[0m: [Errno 17] File exists: 'data/results/naiveB/total-rna'" + ] + } + ], + "execution_count": 6 }, { "cell_type": "markdown", diff --git a/main/como/__init__.py b/main/como/__init__.py index c6ee72e2..c0a9a400 100644 --- a/main/como/__init__.py +++ b/main/como/__init__.py @@ -1,11 +1,6 @@ -import pandas as pd - -from como.project import Config from como.utils import stringlist_to_list - -__all__ = ["stringlist_to_list", "Config"] -__version__ = "1.11.1" +from como.data_types import LogLevel, FilteringTechnique, AdjustmentMethod, Solver -def return_placeholder_data() -> pd.DataFrame: - return pd.DataFrame(data=0, index=pd.Index(data=[0], name="entrez_gene_id"), columns=["expressed", "top"]) +__all__ = ["stringlist_to_list", "LogLevel", "FilteringTechnique", "AdjustmentMethod", "Solver"] +__version__ = "1.11.1" diff --git a/main/como/utils.py b/main/como/utils.py index 74d924cf..344ef03f 100644 --- a/main/como/utils.py +++ b/main/como/utils.py @@ -277,3 +277,6 @@ def _num_rows(item: pd.DataFrame | npt.NDArray) -> int: def _num_columns(item: pd.DataFrame | npt.NDArray) -> int: return item.shape[0] +def return_placeholder_data() -> pd.DataFrame: + return pd.DataFrame(data=0, index=pd.Index(data=[0], name="entrez_gene_id"), columns=["expressed", "top"]) + From b5d0a9145a34760b53eca4f60fd320d81cb816fa Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 13:53:07 -0600 Subject: [PATCH 036/265] fix: properly return row and column values Signed-off-by: Josh Loecker --- main/como/utils.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/main/como/utils.py b/main/como/utils.py index 344ef03f..7bd125dd 100644 --- a/main/como/utils.py +++ b/main/como/utils.py @@ -272,11 +272,13 @@ def _listify(value): def _num_rows(item: pd.DataFrame | npt.NDArray) -> int: - return item.shape[1] + return item.shape[0] def _num_columns(item: pd.DataFrame | npt.NDArray) -> int: - return item.shape[0] + return item.shape[1] + + def return_placeholder_data() -> pd.DataFrame: return pd.DataFrame(data=0, index=pd.Index(data=[0], name="entrez_gene_id"), columns=["expressed", "top"]) From 4079deb64bc95d55e8c20f64cb57649e7ece70e9 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 13:53:53 -0600 Subject: [PATCH 037/265] feat: added function to set up logging throughout COMO Signed-off-by: Josh Loecker --- main/como/utils.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/main/como/utils.py b/main/como/utils.py index 7bd125dd..18826666 100644 --- a/main/como/utils.py +++ b/main/como/utils.py @@ -282,3 +282,12 @@ def _num_columns(item: pd.DataFrame | npt.NDArray) -> int: def return_placeholder_data() -> pd.DataFrame: return pd.DataFrame(data=0, index=pd.Index(data=[0], name="entrez_gene_id"), columns=["expressed", "top"]) + +def _set_up_logging( + level: LogLevel, + location: str | TextIOWrapper, + formatting: str = LOG_FORMAT, +): + with contextlib.suppress(ValueError): + logger.remove(0) + logger.add(sink=location, level=level.value, format=formatting) From bf7f139677207ed51675e69abf2115fd2ad21622 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 13:54:38 -0600 Subject: [PATCH 038/265] feat: added function to log and raise an error --- main/como/utils.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/main/como/utils.py b/main/como/utils.py index 18826666..e3788878 100644 --- a/main/como/utils.py +++ b/main/como/utils.py @@ -291,3 +291,21 @@ def _set_up_logging( with contextlib.suppress(ValueError): logger.remove(0) logger.add(sink=location, level=level.value, format=formatting) + + +def _log_and_raise_error( + message: str, + *, + error: type[BaseException], + level: LogLevel, +) -> None: + caller = logger.opt(depth=1) + match level: + case LogLevel.ERROR: + caller.error(message) + case LogLevel.CRITICAL: + caller.critical(message) + case _: + raise ValueError(f"When raising an error, LogLevel.ERROR or LogLevel.CRITICAL must be used. Got: {level}") + + raise error(message) From 237d1fc5ffb87000a6df15d7767a548e7dfad0c9 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 13:55:25 -0600 Subject: [PATCH 039/265] refactor!: moved Algorithms to data_types The Algorithms class fits better as a data type --- main/como/data_types.py | 5 +++++ main/como/utils.py | 21 --------------------- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/main/como/data_types.py b/main/como/data_types.py index a544aa8d..a9da5d56 100644 --- a/main/como/data_types.py +++ b/main/como/data_types.py @@ -25,6 +25,11 @@ def from_string(value: str) -> RNAPrepMethod: case _: possible_values = [t.value for t in RNAPrepMethod] raise ValueError(f"Filtering technique must be one of {possible_values}; got: {value}") +class Algorithm(Enum): + GIMME = "GIMME" + FASTCORE = "FASTCORE" + IMAT = "IMAT" + TINIT = "TINIT" class FilteringTechnique(Enum): diff --git a/main/como/utils.py b/main/como/utils.py index e3788878..476d48cd 100644 --- a/main/como/utils.py +++ b/main/como/utils.py @@ -23,27 +23,6 @@ __all__ = ["Compartments", "split_gene_expression_data", "stringlist_to_list", "suppress_stdout"] -class Algorithm(Enum): - GIMME = "GIMME" - FASTCORE = "FASTCORE" - IMAT = "IMAT" - TINIT = "TINIT" - - @staticmethod - def from_string(value: str) -> Algorithm: - match value.lower(): - case "gimme": - return Algorithm.GIMME - case "fastcore": - return Algorithm.FASTCORE - case "imat": - return Algorithm.IMAT - case "tinit": - return Algorithm.TINIT - case _: - raise ValueError(f"Unknown solver: {value}") - - class Compartments: """Convert from compartment "long-hand" to "short-hand". From 34ccd44ab0eaf7090dbd71946d60886b0188d74f Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 13:56:23 -0600 Subject: [PATCH 040/265] refactor!: moved Compartments to data_types Renamed to CobraCompartments --- main/como/data_types.py | 68 +++++++++++++++++++++++++++++++++++++++++ main/como/utils.py | 61 ------------------------------------ 2 files changed, 68 insertions(+), 61 deletions(-) diff --git a/main/como/data_types.py b/main/como/data_types.py index a9da5d56..95f99f7a 100644 --- a/main/como/data_types.py +++ b/main/como/data_types.py @@ -60,3 +60,71 @@ def from_string(value: str) -> FilteringTechnique: PATH_TYPE = str | Path RNA_TYPE = Literal["total", "mrna"] LOG_LEVEL = Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] + +class CobraCompartments: + """Convert from compartment "long-hand" to "short-hand". + + Shorthand from: https://cobrapy.readthedocs.io/en/latest/_modules/cobra/medium/annotations.html + + "Extracellular" -> "e" + "golgi" -> "g" + """ + + SHORTHAND: ClassVar[dict[str, list[str]]] = { + "ce": ["cell envelope"], + "c": [ + "cytoplasm", + "cytosol", + "default", + "in", + "intra cellular", + "intracellular", + "intracellular region", + "intracellular space", + ], + "er": ["endoplasmic reticulum"], + "erm": ["endoplasmic reticulum membrane"], + "e": [ + "extracellular", + "extraorganism", + "out", + "extracellular space", + "extra organism", + "extra cellular", + "extra-organism", + "external", + "external medium", + ], + "f": ["flagellum", "bacterial-type flagellum"], + "g": ["golgi", "golgi apparatus"], + "gm": ["golgi membrane"], + "h": ["chloroplast"], + "l": ["lysosome"], + "im": ["mitochondrial intermembrane space"], + "mm": ["mitochondrial membrane"], + "m": ["mitochondrion", "mitochondria"], + "n": ["nucleus"], + "p": ["periplasm", "periplasmic space"], + "x": ["peroxisome", "glyoxysome"], + "u": ["thylakoid"], + "vm": ["vacuolar membrane"], + "v": ["vacuole"], + "w": ["cell wall"], + "s": ["eyespot", "eyespot apparatus", "stigma"], + } + + _REVERSE_LOOKUP: ClassVar[dict[str, list[str]]] = { + value.lower(): key for key, values in SHORTHAND.items() for value in values + } + + @classmethod + def get_shorthand(cls, longhand: str) -> str | None: + """Get the short-hand compartment name from the long-hand name.""" + return cls._REVERSE_LOOKUP.get(longhand.lower(), None) + + @classmethod + def get_longhand(cls, shorthand: str) -> str | None: + """Get the long-hand compartment name from the short-hand name.""" + longhand = cls.SHORTHAND.get(shorthand.lower(), None) + return longhand[0] if longhand else None + diff --git a/main/como/utils.py b/main/como/utils.py index 476d48cd..c87eb8d7 100644 --- a/main/como/utils.py +++ b/main/como/utils.py @@ -23,67 +23,6 @@ __all__ = ["Compartments", "split_gene_expression_data", "stringlist_to_list", "suppress_stdout"] -class Compartments: - """Convert from compartment "long-hand" to "short-hand". - - Shorthand from: https://cobrapy.readthedocs.io/en/latest/_modules/cobra/medium/annotations.html - - "Extracellular" -> "e" - "golgi" -> "g" - """ - - SHORTHAND: ClassVar[dict[str, list[str]]] = { - "ce": ["cell envelope"], - "c": [ - "cytoplasm", - "cytosol", - "default", - "in", - "intra cellular", - "intracellular", - "intracellular region", - "intracellular space", - ], - "er": ["endoplasmic reticulum"], - "erm": ["endoplasmic reticulum membrane"], - "e": [ - "extracellular", - "extraorganism", - "out", - "extracellular space", - "extra organism", - "extra cellular", - "extra-organism", - "external", - "external medium", - ], - "f": ["flagellum", "bacterial-type flagellum"], - "g": ["golgi", "golgi apparatus"], - "gm": ["golgi membrane"], - "h": ["chloroplast"], - "l": ["lysosome"], - "im": ["mitochondrial intermembrane space"], - "mm": ["mitochondrial membrane"], - "m": ["mitochondrion", "mitochondria"], - "n": ["nucleus"], - "p": ["periplasm", "periplasmic space"], - "x": ["peroxisome", "glyoxysome"], - "u": ["thylakoid"], - "vm": ["vacuolar membrane"], - "v": ["vacuole"], - "w": ["cell wall"], - "s": ["eyespot", "eyespot apparatus", "stigma"], - } - - _REVERSE_LOOKUP: ClassVar[dict[str, list[str]]] = { - value.lower(): key for key, values in SHORTHAND.items() for value in values - } - - @classmethod - def get(cls, longhand: str) -> str | None: - """Get the short-hand compartment name from the long-hand name.""" - return cls._REVERSE_LOOKUP.get(longhand.lower(), None) - def stringlist_to_list(stringlist: str | list[str]) -> list[str]: """Convert a string from the command line into a Python list. From 038ab174fdcf9e007a6eaea4583d2a633440095b Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 13:56:58 -0600 Subject: [PATCH 041/265] refactor: re-organized constants --- main/como/data_types.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/main/como/data_types.py b/main/como/data_types.py index 95f99f7a..a1cbc5b6 100644 --- a/main/como/data_types.py +++ b/main/como/data_types.py @@ -4,6 +4,13 @@ from pathlib import Path from typing import Literal +PATH_TYPE = str | Path +LOG_FORMAT = ( + "{time:YYYY-MM-DD HH:mm:ss} | " + "{level:<8} | " + "{name}:{line} - {message}" +) + class RNAPrepMethod(Enum): TOTAL = "total" From c337e4da747a8775f89875592a998254df27ef23 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 13:58:05 -0600 Subject: [PATCH 042/265] fix: removed items from __all__ that were moved --- main/como/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/como/utils.py b/main/como/utils.py index c87eb8d7..05e8b5e3 100644 --- a/main/como/utils.py +++ b/main/como/utils.py @@ -20,8 +20,8 @@ ) from loguru import logger -__all__ = ["Compartments", "split_gene_expression_data", "stringlist_to_list", "suppress_stdout"] +__all__ = ["split_gene_expression_data", "stringlist_to_list", "suppress_stdout"] def stringlist_to_list(stringlist: str | list[str]) -> list[str]: From 99676edef6ce1722b284d3191ec378162a658321 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 13:58:53 -0600 Subject: [PATCH 043/265] refactor: imported required packages and types --- main/como/utils.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/main/como/utils.py b/main/como/utils.py index 05e8b5e3..5065c786 100644 --- a/main/como/utils.py +++ b/main/como/utils.py @@ -1,16 +1,21 @@ from __future__ import annotations +import asyncio import contextlib +import functools +import inspect import io import sys from collections.abc import Iterator -from enum import Enum +from concurrent.futures import ThreadPoolExecutor +from io import TextIOWrapper from pathlib import Path -from typing import ClassVar +from typing import Union import aiofiles import numpy.typing as npt import pandas as pd +import scanpy as sc from fast_bioservices import BioDBNet, Output, Taxon from fast_bioservices.pipeline import ( determine_gene_type, @@ -20,6 +25,7 @@ ) from loguru import logger +from como.data_types import LOG_FORMAT, Algorithm, LogLevel __all__ = ["split_gene_expression_data", "stringlist_to_list", "suppress_stdout"] From 8662f7c609b2269907ce4bee19933afc9839564e Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:00:20 -0600 Subject: [PATCH 044/265] fix: added Algorithm as top level import --- main/como/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/como/__init__.py b/main/como/__init__.py index c0a9a400..480993c9 100644 --- a/main/como/__init__.py +++ b/main/como/__init__.py @@ -1,5 +1,5 @@ from como.utils import stringlist_to_list -from como.data_types import LogLevel, FilteringTechnique, AdjustmentMethod, Solver +from como.data_types import LogLevel, FilteringTechnique, AdjustmentMethod, Solver, Algorithm __all__ = ["stringlist_to_list", "LogLevel", "FilteringTechnique", "AdjustmentMethod", "Solver"] From c454e8df97dd93a6f1dbf6b904de516925ab73e1 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:01:32 -0600 Subject: [PATCH 045/265] fix: added CobraCompartments as top-level import --- main/como/__init__.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/main/como/__init__.py b/main/como/__init__.py index 480993c9..660fc21f 100644 --- a/main/como/__init__.py +++ b/main/como/__init__.py @@ -1,6 +1,14 @@ from como.utils import stringlist_to_list -from como.data_types import LogLevel, FilteringTechnique, AdjustmentMethod, Solver, Algorithm +from como.data_types import LogLevel, FilteringTechnique, AdjustmentMethod, Solver, Algorithm, CobraCompartments -__all__ = ["stringlist_to_list", "LogLevel", "FilteringTechnique", "AdjustmentMethod", "Solver"] +__all__ = [ + "AdjustmentMethod", + "Algorithm", + "CobraCompartments", + "FilteringTechnique", + "LogLevel", + "Solver", + "stringlist_to_list", +] __version__ = "1.11.1" From 510c77c751176b9da96b92a7478b90a66374b343 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:02:15 -0600 Subject: [PATCH 046/265] fix: process ids as string type --- main/como/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/como/utils.py b/main/como/utils.py index 5065c786..164012d4 100644 --- a/main/como/utils.py +++ b/main/como/utils.py @@ -88,7 +88,7 @@ def split_gene_expression_data( single_gene_names = expression_data[~expression_data["entrez_gene_id"].astype(str).str.contains("//")] multiple_gene_names = expression_data[expression_data["entrez_gene_id"].astype(str).str.contains("//")] split_gene_names = multiple_gene_names.assign( - entrez_gene_id=multiple_gene_names["entrez_gene_id"].str.split("///") + entrez_gene_id=multiple_gene_names["entrez_gene_id"].astype(str).str.split("///") ).explode("entrez_gene_id") gene_expressions = pd.concat([single_gene_names, split_gene_names], axis=0, ignore_index=True) From 3e934884fb826130e89f2ea6e76bff7b1bbd5c82 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:04:00 -0600 Subject: [PATCH 047/265] refactor: combine async file reading Combine asynchronous file reading (csv, excel, etc.) into a single function --- main/como/utils.py | 44 ++++++++++++++++---------------------------- 1 file changed, 16 insertions(+), 28 deletions(-) diff --git a/main/como/utils.py b/main/como/utils.py index 164012d4..e14eedc3 100644 --- a/main/como/utils.py +++ b/main/como/utils.py @@ -130,40 +130,28 @@ async def _format_determination( return cohersion -async def _async_read_csv(path: Path, **kwargs) -> pd.DataFrame: - """Asynchronously reads a CSV file and returns a pandas DataFrame. +async def _read_file( + path: Path | io.StringIO | None, + h5ad_as_df: bool = True, + **kwargs, +) -> pd.DataFrame | sc.AnnData | None: + """Asynchronously read a filepath and return a pandas DataFrame. - :param path: The path to read from - :param kwargs: Additional arguments to pass to pandas.read_csv - :return: A pandas DataFrame - """ - if not path.exists(): - raise FileNotFoundError(f"File {path} does not exist") - if path.suffix not in {".csv", ".tsv"}: - raise ValueError(f"File {path} is not a CSV file") - - kwargs.setdefault("sep", "," if path.suffix == ".csv" else "\t") - async with aiofiles.open(path) as f: - content = await f.read() - return pd.read_csv(io.StringIO(content), **kwargs) - - -async def _async_read_excel(path: Path, **kwargs) -> pd.DataFrame: - """Asynchronously reads an Excel file and returns a pandas DataFrame. + If the provided path is None, None will also be returned. + None may be provided to this function so that `asyncio.gather` can safely be used on all sources + (trna, mrna, scrna, proteomics) without needing to check if the user has provided those sources :param path: The path to read from - :param kwargs: Additional arguments to pass to pandas.read_excel - :return: A pandas DataFrame + :param kwargs: Additional arguments to pass to pandas.read_csv, pandas.read_excel, + or scanpy.read_h5ad, depending on the filepath provided + :return: None, or a pandas DataFrame or AnnData """ + if not path: + return None + if not path.exists(): + logger.critical(f"File {path} does not exist") raise FileNotFoundError(f"File {path} does not exist") - if path.suffix not in {".xls", ".xlsx"}: - raise ValueError(f"File {path} is not an Excel file") - - async with aiofiles.open(path, "rb") as f: - content = await f.read() - return pd.read_excel(io.StringIO(content.decode()), **kwargs) - def is_notebook() -> bool: """Check if the current environment is a Jupyter Notebook. From e99d3bd8313cd32013adc3465ae19e0efbb671a5 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:04:17 -0600 Subject: [PATCH 048/265] refactor: remove un-used function --- main/como/utils.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/main/como/utils.py b/main/como/utils.py index e14eedc3..ac16f13f 100644 --- a/main/como/utils.py +++ b/main/como/utils.py @@ -153,18 +153,6 @@ async def _read_file( logger.critical(f"File {path} does not exist") raise FileNotFoundError(f"File {path} does not exist") -def is_notebook() -> bool: - """Check if the current environment is a Jupyter Notebook. - - :returns: True if the current environment is a Jupyter Notebook, False otherwise. - """ - try: - from IPython import get_ipython - - return get_ipython() is not None - except ModuleNotFoundError: - return False - async def convert_gene_data(values: list[str], taxon_id: int | str | Taxon) -> pd.DataFrame: gene_type = await determine_gene_type(values) From c1c6d00a1d6b66fe809fda698850057513c42986 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:08:14 -0600 Subject: [PATCH 049/265] refactor: fix async reading of data --- main/como/utils.py | 45 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/main/como/utils.py b/main/como/utils.py index ac16f13f..8148f755 100644 --- a/main/como/utils.py +++ b/main/como/utils.py @@ -153,15 +153,44 @@ async def _read_file( logger.critical(f"File {path} does not exist") raise FileNotFoundError(f"File {path} does not exist") + # StringIO is used if a CSV file is read using open() directly + if isinstance(path, io.StringIO): + return pd.DataFrame(path, **kwargs) + + match path.suffix: + case ".csv" | ".tsv": + kwargs.setdefault("sep", "," if path.suffix == ".csv" else "\t") + async with aiofiles.open(path) as f: + content = await f.read() + return pd.read_csv(io.StringIO(content), **kwargs) + case ".xlsx" | ".xls": + loop = asyncio.get_running_loop() + with ThreadPoolExecutor(max_workers=1) as pool: + # pass kwargs as args + func = functools.partial(pd.read_excel, **kwargs) + return await loop.run_in_executor(pool, func, path) + case ".h5ad": + loop = asyncio.get_running_loop() + with ThreadPoolExecutor(max_workers=1) as pool: + func = functools.partial(sc.read_h5ad, **kwargs) + adata: sc.AnnData = await loop.run_in_executor(pool, func, path) + + if h5ad_as_df: + df = adata.to_df().T + df.index.name = "gene_symbol" + df.reset_index(inplace=True) + return df + return adata + case _: + logger.critical( + f"Unknown file extension '{path.suffix}'. Valid options are '.tsv', '.csv', '.xlsx', '.xls', or '.h5ad'" + ) + raise ValueError( + f"Unknown file extension '{path.suffix}'. " + f"Valid options are '.tsv', '.csv', '.xlsx', '.xls', or '.h5ad'." + ) + -async def convert_gene_data(values: list[str], taxon_id: int | str | Taxon) -> pd.DataFrame: - gene_type = await determine_gene_type(values) - if all(v == "gene_symbol" for v in gene_type.values()): - return await gene_symbol_to_ensembl_and_gene_id(values, taxon=taxon_id) - elif all(v == "ensembl_gene_id" for v in gene_type.values()): - return await ensembl_to_gene_id_and_symbol(ids=values, taxon=taxon_id) - elif all(v == "entrez_gene_id" for v in gene_type.values()): - return await gene_id_to_ensembl_and_gene_symbol(ids=values, taxon=taxon_id) else: raise ValueError("Gene data must be of the same type (i.e., all Ensembl, Entrez, or Gene Symbols)") From 5c912b32ace05e5a483758c5ce33f59d57f1562f Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:08:30 -0600 Subject: [PATCH 050/265] feat: allow passing strings for dataframes --- main/como/utils.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/main/como/utils.py b/main/como/utils.py index 8148f755..a25c8b3e 100644 --- a/main/como/utils.py +++ b/main/como/utils.py @@ -191,8 +191,31 @@ async def _read_file( ) +async def get_missing_gene_data(values: list[str] | pd.DataFrame, taxon_id: int | str | Taxon) -> pd.DataFrame: + if isinstance(values, list): + gene_type = await determine_gene_type(values) + if all(v == "gene_symbol" for v in gene_type.values()): + return await gene_symbol_to_ensembl_and_gene_id(values, taxon=taxon_id) + elif all(v == "ensembl_gene_id" for v in gene_type.values()): + return await ensembl_to_gene_id_and_symbol(ids=values, taxon=taxon_id) + elif all(v == "entrez_gene_id" for v in gene_type.values()): + return await gene_id_to_ensembl_and_gene_symbol(ids=values, taxon=taxon_id) + else: + logger.critical("Gene data must be of the same type (i.e., all Ensembl, Entrez, or Gene Symbols)") + raise ValueError("Gene data must be of the same type (i.e., all Ensembl, Entrez, or Gene Symbols)") else: - raise ValueError("Gene data must be of the same type (i.e., all Ensembl, Entrez, or Gene Symbols)") + values: pd.DataFrame # Re-define type to assist in type hinting + if "gene_symbol" in values: + return await get_missing_gene_data(values["gene_symbol"].tolist(), taxon_id=taxon_id) + elif "entrez_gene_id" in values: + return await get_missing_gene_data(values["entrez_gene_id"].tolist(), taxon_id=taxon_id) + elif "ensembl_gene_id" in values: + return await get_missing_gene_data(values["ensembl_gene_id"].tolist(), taxon_id=taxon_id) + else: + logger.critical("Unable to find 'gene_symbol', 'entrez_gene_id', or 'ensembl_gene_id' in the input matrix.") + raise ValueError( + "Unable to find 'gene_symbol', 'entrez_gene_id', or 'ensembl_gene_id' in the input matrix." + ) def _listify(value): From e942b856d220c84e51d3192c7d3706c0869de30c Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:08:54 -0600 Subject: [PATCH 051/265] fix: importing of required and unused modules --- main/como/rnaseq_preprocess.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index b869a97e..ed598adc 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -1,7 +1,6 @@ from __future__ import annotations import asyncio -import contextlib import re import sys from dataclasses import dataclass, field @@ -13,13 +12,12 @@ import aiofiles import numpy as np import pandas as pd -import scanpy as sc from fast_bioservices.biothings.mygene import MyGene from fast_bioservices.pipeline import ensembl_to_gene_id_and_symbol, gene_symbol_to_ensembl_and_gene_id from loguru import logger -from como.data_types import LOG_LEVEL, PATH_TYPE, RNA_TYPE, RNAPrepMethod -from como.utils import _listify +from como.data_types import PATH_TYPE, LogLevel, RNAType +from como.utils import _listify, _read_file, _set_up_logging @dataclass From 0345a148c2645a93533c21bf393e55b25f80acd8 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:18:57 -0600 Subject: [PATCH 052/265] feat: use new log_and_raise_error --- main/como/rnaseq_preprocess.py | 150 +++++++++++++++++++++++---------- 1 file changed, 107 insertions(+), 43 deletions(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index ed598adc..36ebe264 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -17,7 +17,7 @@ from loguru import logger from como.data_types import PATH_TYPE, LogLevel, RNAType -from como.utils import _listify, _read_file, _set_up_logging +from como.utils import _listify, _log_and_raise_error, _read_file, _set_up_logging @dataclass @@ -36,7 +36,11 @@ def num_genes(self) -> int: @classmethod async def build_from_tab(cls, filepath: Path) -> _STARinformation: if filepath.suffix != ".tab": - raise ValueError(f"Building STAR information requires a '.tab' file; received: '{filepath}'") + _log_and_raise_error( + f"Building STAR information requires a '.tab' file; received: '{filepath}'", + error=ValueError, + level=LogLevel.ERROR, + ) async with aiofiles.open(filepath) as i_stream: unmapped = await i_stream.readline() @@ -90,25 +94,41 @@ def __post_init__(self): self.__sample_names = [f.stem for f in self.count_files] if len(self.count_files) != len(self.strand_files): - raise ValueError( - f"Unequal number of count files and strand files for study '{self.study_name}'. " - f"Found {len(self.count_files)} count files and {len(self.strand_files)} strand files." + _log_and_raise_error( + ( + f"Unequal number of count files and strand files for study '{self.study_name}'. " + f"Found {len(self.count_files)} count files and {len(self.strand_files)} strand files." + ), + error=ValueError, + level=LogLevel.ERROR, ) if self.num_samples != len(self.count_files): - raise ValueError( - f"Unequal number of samples and count files for study '{self.study_name}'. " - f"Found {self.num_samples} samples and {len(self.count_files)} count files." + _log_and_raise_error( + ( + f"Unequal number of samples and count files for study '{self.study_name}'. " + f"Found {self.num_samples} samples and {len(self.count_files)} count files." + ), + error=ValueError, + level=LogLevel.ERROR, ) if self.num_samples != len(self.strand_files): - raise ValueError( - f"Unequal number of samples and strand files for study '{self.study_name}'. " - f"Found {self.num_samples} samples and {len(self.strand_files)} strand files." + _log_and_raise_error( + ( + f"Unequal number of samples and strand files for study '{self.study_name}'. " + f"Found {self.num_samples} samples and {len(self.strand_files)} strand files." + ), + error=ValueError, + level=LogLevel.ERROR, ) if self.__num_samples == 1: - raise ValueError(f"Only one sample exists for study {self.study_name}. Provide at least two samples") + _log_and_raise_error( + f"Only one sample exists for study {self.study_name}. Provide at least two samples", + error=ValueError, + level=LogLevel.ERROR, + ) self.count_files.sort() self.strand_files.sort() @@ -127,10 +147,14 @@ def _organize_gene_counts_files(data_dir: Path) -> list[_StudyMetrics]: strandedness_directories: list[Path] = sorted([p for p in strand_dir.glob("*") if not p.name.startswith(".")]) if len(gene_counts_directories) != len(strandedness_directories): - raise ValueError( - f"Unequal number of gene count directories and strandedness directories. " - f"Found {len(gene_counts_directories)} gene count directories and {len(strandedness_directories)} strandedness directories." # noqa: E501 - f"\nGene count directory: {gene_count_dir}\nStrandedness directory: {strand_dir}" + _log_and_raise_error( + ( + f"Unequal number of gene count directories and strandedness directories. " + f"Found {len(gene_counts_directories)} gene count directories and {len(strandedness_directories)} strandedness directories." # noqa: E501 + f"\nGene count directory: {gene_count_dir}\nStrandedness directory: {strand_dir}" + ), + error=ValueError, + level=LogLevel.ERROR, ) # For each study, collect gene count files, fragment files, insert size files, layouts, and strandedness information @@ -139,9 +163,15 @@ def _organize_gene_counts_files(data_dir: Path) -> list[_StudyMetrics]: count_files = list(gene_dir.glob("*.tab")) strand_files = list(strand_dir.glob("*.txt")) if len(count_files) == 0: - raise ValueError(f"No count files found for study '{gene_dir.stem}'.") + _log_and_raise_error( + f"No count files found for study '{gene_dir.stem}'.", error=ValueError, level=LogLevel.ERROR + ) if len(strand_files) == 0: - raise ValueError(f"No strandedness files found for study '{gene_dir.stem}'.") + _log_and_raise_error( + f"No strandedness files found for study '{gene_dir.stem}'.", + error=ValueError, + level=LogLevel.ERROR, + ) study_metrics.append( _StudyMetrics( @@ -160,9 +190,13 @@ async def _process_first_multirun_sample(strand_file: Path, all_counts_files: li strand_information = strand_file.read_text().rstrip("\n").lower() if strand_information not in ("none", "first_read_transcription_strand", "second_read_transcription_strand"): - raise ValueError( - f"Unrecognized Strand Information: {strand_information}; " - f"expected 'none', 'first_read_transcription_strand', or 'second_read_transcription_strand'" + _log_and_raise_error( + ( + f"Unrecognized Strand Information: {strand_information}; " + f"expected 'none', 'first_read_transcription_strand', or 'second_read_transcription_strand'" + ), + error=ValueError, + level=LogLevel.ERROR, ) if strand_information == "none": @@ -191,9 +225,13 @@ async def _process_standard_replicate(counts_file: Path, strand_file: Path, samp strand_information = strand_file.read_text().rstrip("\n").lower() if strand_information not in ("none", "first_read_transcription_strand", "second_read_transcription_strand"): - raise ValueError( - f"Unrecognized Strand Information: {strand_information}; " - f"expected 'none', 'first_read_transcription_strand', or 'second_read_transcription_strand'" + _log_and_raise_error( + ( + f"Unrecognized Strand Information: {strand_information}; " + f"expected 'none', 'first_read_transcription_strand', or 'second_read_transcription_strand'" + ), + error=ValueError, + level=LogLevel.ERROR, ) if strand_information == "none": @@ -306,7 +344,9 @@ async def _create_config_df( # noqa: C901 preparation_method: list[str] = [] if len(gene_counts_files) == 0: - raise FileNotFoundError(f"No gene count files found in '{gene_counts_dir}'.") + _log_and_raise_error( + f"No gene count files found in '{gene_counts_dir}'.", error=FileNotFoundError, level=LogLevel.ERROR + ) for gene_count_filename in sorted(gene_counts_files): # Match S___R___r___ @@ -314,11 +354,15 @@ async def _create_config_df( # noqa: C901 # (?:r\d{1,3})? optionally matches a "r" followed by three digits label = re.findall(r"S\d{1,3}R\d{1,3}(?:r\d{1,3})?", gene_count_filename.as_posix())[0] if not label: - raise ValueError( - f"\n\nFilename of '{gene_count_filename}' is not valid. " - f"Should be 'contextName_SXRYrZ.tab', where X is the study/batch number, Y is the replicate number, " - f"and Z is the run number." - "\n\nIf not a multi-run sample, exclude 'rZ' from the filename." + _log_and_raise_error( + ( + f"\n\nFilename of '{gene_count_filename}' is not valid. " + f"Should be 'contextName_SXRYrZ.tab', where X is the study/batch number, Y is the replicate number, " + f"and Z is the run number." + "\n\nIf not a multi-run sample, exclude 'rZ' from the filename." + ), + error=ValueError, + level=LogLevel.ERROR, ) study_number = re.findall(r"S\d{1,3}", label)[0] @@ -355,9 +399,13 @@ async def _create_config_df( # noqa: C901 with layout_files[0].open("r") as file: layout = file.read().strip() elif len(layout_files) > 1: - raise ValueError( - f"Multiple matching layout files for {label}, " - f"make sure there is only one copy for each replicate in COMO_input" + _log_and_raise_error( + ( + f"Multiple matching layout files for {label}, " + f"make sure there is only one copy for each replicate in COMO_input" + ), + error=ValueError, + level=LogLevel.ERROR, ) strand = "UNKNOWN" @@ -371,9 +419,13 @@ async def _create_config_df( # noqa: C901 with strand_files[0].open("r") as file: strand = file.read().strip() elif len(strand_files) > 1: - raise ValueError( - f"Multiple matching strandedness files for {label}, " - f"make sure there is only one copy for each replicate in COMO_input" + _log_and_raise_error( + ( + f"Multiple matching strandedness files for {label}, " + f"make sure there is only one copy for each replicate in COMO_input" + ), + error=ValueError, + level=LogLevel.ERROR, ) prep = "total" @@ -383,11 +435,19 @@ async def _create_config_df( # noqa: C901 with prep_files[0].open("r") as file: prep = file.read().strip().lower() if prep not in ["total", "mrna"]: - raise ValueError(f"Prep method must be either 'total' or 'mrna' for {label}") + _log_and_raise_error( + f"Prep method must be either 'total' or 'mrna' for {label}", + error=ValueError, + level=LogLevel.ERROR, + ) elif len(prep_files) > 1: - raise ValueError( - f"Multiple matching prep files for {label}, " - f"make sure there is only one copy for each replicate in COMO_input" + _log_and_raise_error( + ( + f"Multiple matching prep files for {label}, " + f"make sure there is only one copy for each replicate in COMO_input" + ), + error=ValueError, + level=LogLevel.ERROR, ) mean_fragment_size = 100 @@ -417,9 +477,13 @@ async def _create_config_df( # noqa: C901 mean_fragment_size = sum(mean_fragment_sizes * library_sizes) / sum(library_sizes) elif len(frag_files) > 1: - raise ValueError( - f"Multiple matching fragment files for {label}, " - f"make sure there is only one copy for each replicate in COMO_input" + _log_and_raise_error( + ( + f"Multiple matching fragment files for {label}, " + f"make sure there is only one copy for each replicate in COMO_input" + ), + error=ValueError, + level=LogLevel.ERROR, ) sample_names.append(f"{context_name}_{study_number}{rep_number}") From 4d66cd38288afec517be45869dd8783e47ba13b0 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:19:10 -0600 Subject: [PATCH 053/265] feat: set appropriate logging --- main/como/rnaseq_preprocess.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index 36ebe264..d2b5c634 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -667,13 +667,7 @@ async def rnaseq_preprocess( :param log_level: The logging level :param log_location: The logging location """ - with contextlib.suppress(ValueError): - logger.remove(0) - logger.add( - sink=log_location, - level=log_level, - format="{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {name}:{line} - {message}", # noqa: E501 - ) + _set_up_logging(level=log_level, location=log_location) output_gene_info_filepath = output_gene_info_filepath.resolve() como_context_dir = como_context_dir.resolve() From 40cdfd47c3278db62295b2ffd6e6c5908838462c Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:19:51 -0600 Subject: [PATCH 054/265] feat: combine lines async file reading --- main/como/rnaseq_preprocess.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index d2b5c634..a34b7abd 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -54,8 +54,7 @@ async def build_from_tab(cls, filepath: Path) -> _STARinformation: num_ambiguous = [int(i) for i in ambiguous.rstrip("\n").split("\t")[1:]] remainder = await i_stream.read() - string_io = StringIO(remainder) - df = pd.read_csv(string_io, sep="\t", header=None) + df = await _read_file(StringIO(remainder), sep="\t", header=None) df.columns = [ "ensembl_gene_id", "unstranded_rna_counts", From 509ed961dc0768b6f5980fe5a12563b6c1f1f55d Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:20:39 -0600 Subject: [PATCH 055/265] feat: create Enum from rna types --- main/como/data_types.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/main/como/data_types.py b/main/como/data_types.py index a1cbc5b6..0c5d00bc 100644 --- a/main/como/data_types.py +++ b/main/como/data_types.py @@ -68,6 +68,12 @@ def from_string(value: str) -> FilteringTechnique: RNA_TYPE = Literal["total", "mrna"] LOG_LEVEL = Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] +class RNAType(Enum): + TRNA = "total" + MRNA = "mrna" + SCRNA = "scrna" + + class CobraCompartments: """Convert from compartment "long-hand" to "short-hand". From 55c04d1a54a5a5484a3f8240cd146a9c19bbe627 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:21:27 -0600 Subject: [PATCH 056/265] fix: use new RNA type enum --- main/como/rnaseq_preprocess.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index a34b7abd..718caa11 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -292,7 +292,7 @@ async def _write_counts_matrix( config_df: pd.DataFrame, como_context_dir: Path, output_counts_matrix_filepath: Path, - rna: RNA_TYPE, + rna: RNAType, ) -> pd.DataFrame: """Create a counts matrix file by reading gene counts table(s).""" study_metrics = _organize_gene_counts_files(data_dir=como_context_dir) @@ -304,12 +304,12 @@ async def _write_counts_matrix( for count in counts: final_matrix = count if final_matrix.empty else pd.merge(final_matrix, count, on="ensembl_gene_id", how="outer") - rna_specific_sample_names = config_df.loc[config_df["library_prep"] == rna, "sample_name"].tolist() + rna_specific_sample_names = config_df.loc[config_df["library_prep"] == rna.value, "sample_name"].tolist() final_matrix = final_matrix[["ensembl_gene_id", *rna_specific_sample_names]] output_counts_matrix_filepath.parent.mkdir(parents=True, exist_ok=True) final_matrix.to_csv(output_counts_matrix_filepath, index=False) - logger.success(f"Wrote gene count matrix for '{rna}' RNA at '{output_counts_matrix_filepath}'") + logger.success(f"Wrote gene count matrix for '{rna.value}' RNA at '{output_counts_matrix_filepath}'") return final_matrix @@ -450,7 +450,7 @@ async def _create_config_df( # noqa: C901 ) mean_fragment_size = 100 - if len(frag_files) == 0 and prep != RNAPrepMethod.TOTAL.value: + if len(frag_files) == 0 and prep != RNAType.TRNA.value: logger.warning( f"No fragment file found for {label}, using '100'. " "You should define this if you are going to use downstream zFPKM normalization" @@ -571,7 +571,7 @@ async def _create_matrix_file( output_config_filepath: Path, como_context_dir: PATH_TYPE, output_counts_matrix_filepath: Path, - rna: RNA_TYPE, + rna: RNAType, ) -> None: config_df = await _create_config_df(context_name, como_context_dir=como_context_dir) await _write_counts_matrix( @@ -581,7 +581,7 @@ async def _create_matrix_file( rna=rna, ) with pd.ExcelWriter(output_config_filepath) as writer: - subset_config = config_df[config_df["library_prep"] == rna] + subset_config = config_df[config_df["library_prep"] == rna.value] subset_config.to_excel(writer, sheet_name=context_name, header=True, index=False) @@ -597,11 +597,11 @@ async def _process( output_mrna_matrix_filepath: Path | None, cache: bool, ): - rna_types: list[tuple[RNA_TYPE, Path, Path]] = [] + rna_types: list[tuple[RNAType, Path, Path]] = [] if output_trna_config_filepath: - rna_types.append(("total", output_trna_config_filepath, output_trna_matrix_filepath)) + rna_types.append((RNAType.trna, output_trna_config_filepath, output_trna_matrix_filepath)) if output_mrna_config_filepath: - rna_types.append(("mrna", output_mrna_config_filepath, output_mrna_matrix_filepath)) + rna_types.append((RNAType.mrna, output_mrna_config_filepath, output_mrna_matrix_filepath)) # if provided, iterate through como-input specific directories tasks = [] From d7ecd509f181477604baa82b972bca1c69bed445 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:22:28 -0600 Subject: [PATCH 057/265] refactor: convert literals to Enums --- main/como/data_types.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/main/como/data_types.py b/main/como/data_types.py index 0c5d00bc..56e91ef1 100644 --- a/main/como/data_types.py +++ b/main/como/data_types.py @@ -65,8 +65,16 @@ def from_string(value: str) -> FilteringTechnique: PATH_TYPE = str | Path -RNA_TYPE = Literal["total", "mrna"] -LOG_LEVEL = Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] + +class LogLevel(Enum): + TRACE = 5 + DEBUG = 10 + INFO = 20 + SUCCESS = 25 + WARNING = 30 + ERROR = 40 + CRITICAL = 50 + class RNAType(Enum): TRNA = "total" From c69fd1a5793f524fd89b4905b07ba6d4f6acdd19 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:23:17 -0600 Subject: [PATCH 058/265] fix: re-organize code --- main/como/data_types.py | 1 - 1 file changed, 1 deletion(-) diff --git a/main/como/data_types.py b/main/como/data_types.py index 56e91ef1..71cf8668 100644 --- a/main/como/data_types.py +++ b/main/como/data_types.py @@ -64,7 +64,6 @@ def from_string(value: str) -> FilteringTechnique: raise ValueError(f"Got a filtering technique of '{value}'; should be one of: {possible_values}") -PATH_TYPE = str | Path class LogLevel(Enum): TRACE = 5 From 189cfe5c17318f18807209ad01bfaf38961e4d97 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:28:02 -0600 Subject: [PATCH 059/265] fix: added dataclasses for simplification of data --- main/como/data_types.py | 175 +++++++++++++++++++++++++++++++--------- 1 file changed, 135 insertions(+), 40 deletions(-) diff --git a/main/como/data_types.py b/main/como/data_types.py index 71cf8668..e4e7d8b2 100644 --- a/main/como/data_types.py +++ b/main/como/data_types.py @@ -1,8 +1,13 @@ from __future__ import annotations +from collections.abc import Iterator +from dataclasses import dataclass, field, fields from enum import Enum from pathlib import Path -from typing import Literal +from typing import ClassVar, NamedTuple + +import pandas as pd +from loguru import logger PATH_TYPE = str | Path LOG_FORMAT = ( @@ -12,26 +17,15 @@ ) -class RNAPrepMethod(Enum): - TOTAL = "total" - MRNA = "mrna" - SCRNA = "scrna" +class AdjustmentMethod(Enum): + """Adjustment method for expression requirement based on differences in number of provided data source types.""" + + PROGRESSIVE = "progressive" + REGRESSIVE = "regressive" + FLAT = "flat" + CUSTOM = "custom" + - @staticmethod - def from_string(value: str) -> RNAPrepMethod: - """Build a preparation method object from a string.""" - match_value = "".join(c for c in value if c.isascii()).lower() - - match match_value: - case "total" | "trna": - return RNAPrepMethod.TOTAL - case "mrna": - return RNAPrepMethod.MRNA - case "scrna": - return RNAPrepMethod.SCRNA - case _: - possible_values = [t.value for t in RNAPrepMethod] - raise ValueError(f"Filtering technique must be one of {possible_values}; got: {value}") class Algorithm(Enum): GIMME = "GIMME" FASTCORE = "FASTCORE" @@ -42,28 +36,17 @@ class Algorithm(Enum): class FilteringTechnique(Enum): """RNA sequencing filtering capabilities.""" - cpm = "cpm" - zfpkm = "zfpkm" - tpm = "quantile" - umi = "umi" - - @staticmethod - def from_string(value: str) -> FilteringTechnique: - """Create a filtering technique object from a string.""" - match value.lower(): - case "cpm": - return FilteringTechnique.cpm - case "zfpkm": - return FilteringTechnique.zfpkm - case "quantile": - return FilteringTechnique.tpm - case "umi": - return FilteringTechnique.umi - case _: - possible_values = [t.value for t in FilteringTechnique] - raise ValueError(f"Got a filtering technique of '{value}'; should be one of: {possible_values}") + CPM = "cpm" + ZFPKM = "zfpkm" + TPM = "quantile" + UMI = "umi" +class GeneIdentifier(Enum): + ENSEMBL_GENE_ID = "ensembl_gene_id" + ENTREZ_GENE_ID = "entrez_gene_id" + GENE_SYMBOL = "gene_symbol" + class LogLevel(Enum): TRACE = 5 @@ -75,12 +58,33 @@ class LogLevel(Enum): CRITICAL = 50 +class PeakIdentificationParameters(NamedTuple): + height: float + distance: float + + class RNAType(Enum): TRNA = "total" MRNA = "mrna" SCRNA = "scrna" +class Solver(Enum): + """Solver used to seed context specific model.""" + + GLPK = "GLPK" + GUROBI = "GUROBI" + SCIPY = "SCIPY" + GLPK_EXACT = "GLPK_EXACT" + + +class SourceTypes(Enum): + TRNA = "trna" + MRNA = "mrna" + SCRNA = "scrna" + PROTEOMICS = "proteomics" + + class CobraCompartments: """Convert from compartment "long-hand" to "short-hand". @@ -148,3 +152,94 @@ def get_longhand(cls, shorthand: str) -> str | None: longhand = cls.SHORTHAND.get(shorthand.lower(), None) return longhand[0] if longhand else None + +@dataclass +class _BatchEntry: + batch_num: int + sample_names: list[str] + _num_samples: int = field(init=False) + + def __post_init__(self): + self._num_samples = len(self.sample_names) + + @property + def num_samples(self): + return self._num_samples + + +@dataclass +class _CombineOmicsInput: + z_score_matrix: pd.DataFrame + type: SourceTypes + weight: int + + +class _BaseDataType: + """Base class for common data types.""" + + def __getitem__(self, value: str): + """Access matrices using square bracket notation (e.g., `input_matrices['total_rna']`). + + :param value: The name of the matrix to get ('trna', 'mrna', 'scrna', 'proteomics') + :returns: The DataFrame if it exists, None otherwise. + """ + self._validate_attribute(value) + return getattr(self, value) + + def __setitem__(self, key, value): + """Set matrices using square bracket notation (e.g., `input_matrices['total_rna'] = new_df`). + + :param key: The key to set + :param value: The new value + """ + self._validate_attribute(key) + setattr(self, key, value) + + def _validate_attribute(self, key): + if key not in {i.value for i in SourceTypes._member_map_.values()}: + # Unable to use como.utils._log_and_raise_error becuase it results in a circular import + message = f"{key} is not a valid attribute of {SourceTypes.__name__}; got '{key}'" + logger.warning(message) + raise ValueError(message) + + def __iter__(self) -> Iterator[tuple[SourceTypes, pd.DataFrame | None]]: + """Iterate over matrix fields and their names. + + Yields: + A tuple containing (matrix_name, matrix_dataframe). + + """ + for field_ in fields(self): + yield SourceTypes(field_.name), getattr(self, field_.name) + + +@dataclass +class _BatchNames(_BaseDataType): + trna: list[_BatchEntry] + mrna: list[_BatchEntry] + scrna: list[_BatchEntry] + proteomics: list[_BatchEntry] + + +@dataclass +class _InputMatrices(_BaseDataType): + trna: pd.DataFrame | None = None + mrna: pd.DataFrame | None = None + scrna: pd.DataFrame | None = None + proteomics: pd.DataFrame | None = None + + +@dataclass +class _OutputCombinedSourceFilepath(_BaseDataType): + trna: Path | None + mrna: Path | None + scrna: Path | None + proteomics: Path | None + + +@dataclass +class _SourceWeights(_BaseDataType): + trna: int + mrna: int + scrna: int + proteomics: int From 4008dc29283e06c12fcde313938512d3ccd45390 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:32:29 -0600 Subject: [PATCH 060/265] feat: use _log_and_raise_error function --- main/como/cluster_rnaseq.py | 61 ++++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 11 deletions(-) diff --git a/main/como/cluster_rnaseq.py b/main/como/cluster_rnaseq.py index dba5499c..818a45bc 100644 --- a/main/como/cluster_rnaseq.py +++ b/main/como/cluster_rnaseq.py @@ -7,7 +7,8 @@ import numpy as np -from como.utils import stringlist_to_list +from como.data_types import LogLevel +from como.utils import _log_and_raise_error, stringlist_to_list @dataclass @@ -34,43 +35,81 @@ def __post_init__(self): # noqa: C901, ignore too complex self.seed = np.random.randint(0, 100_000) if (isdigit(self.min_active_count) and int(self.min_active_count) < 0) or self.min_active_count != "default": - raise ValueError("--min-count must be either 'default' or an integer > 0") + _log_and_raise_error( + "min_active_count must be either 'default' or an integer > 0", error=ValueError, level=LogLevel.ERROR + ) if (isdigit(self.quantile) and 0 > int(self.quantile) > 100) or self.quantile != "default": - raise ValueError("--quantile must be either 'default' or an integer between 0 and 100") + _log_and_raise_error( + "quantile must be either 'default' or an integer between 0 and 100", + error=ValueError, + level=LogLevel.ERROR, + ) if (isdigit(self.replicate_ratio) and 0 > self.replicate_ratio > 1.0) or self.replicate_ratio != "default": - raise ValueError("--rep-ratio must be either 'default' or a float between 0 and 1") + _log_and_raise_error( + "--rep-ratio must be either 'default' or a float between 0 and 1", + error=ValueError, + level=LogLevel.ERROR, + ) if (isdigit(self.batch_ratio) and 0 > self.batch_ratio > 1.0) or self.batch_ratio != "default": - raise ValueError("--batch-ratio must be either 'default' or a float between 0 and 1") + _log_and_raise_error( + "--batch-ratio must be either 'default' or a float between 0 and 1", + error=ValueError, + level=LogLevel.ERROR, + ) if self.filtering_technique.lower() not in {"quantile", "tpm", "cpm", "zfpkm"}: - raise ValueError("--technique must be either 'quantile', 'tpm', 'cpm', 'zfpkm'") + _log_and_raise_error( + "--technique must be either 'quantile', 'tpm', 'cpm', 'zfpkm'", + error=ValueError, + level=LogLevel.ERROR, + ) if self.filtering_technique.lower() == "tpm": self.filtering_technique = "quantile" if self.cluster_algorithm.lower() not in {"mca", "umap"}: - raise ValueError("--clust_algo must be either 'mca', 'umap'") + _log_and_raise_error( + "--clust_algo must be either 'mca', 'umap'", + error=ValueError, + level=LogLevel.ERROR, + ) if 0 > self.min_distance > 1.0: - raise ValueError("--min_dist must be a float between 0 and 1") + _log_and_raise_error( + "--min_dist must be a float between 0 and 1", + error=ValueError, + level=LogLevel.ERROR, + ) if ( isdigit(self.num_replicate_neighbors) and self.num_replicate_neighbors < 1 ) or self.num_replicate_neighbors != "default": - raise ValueError("--n-neighbors-rep must be either 'default' or an integer > 1") + _log_and_raise_error( + "--n-neighbors-rep must be either 'default' or an integer > 1", + error=ValueError, + level=LogLevel.ERROR, + ) if ( isdigit(self.num_batch_neighbors) and self.num_batch_neighbors < 1 ) or self.num_batch_neighbors != "default": - raise ValueError("--n-neighbors-batch must be either 'default' or an integer > 1") + _log_and_raise_error( + "--n-neighbors-batch must be either 'default' or an integer > 1", + error=ValueError, + level=LogLevel.ERROR, + ) if ( isdigit(self.num_context_neighbors) and self.num_context_neighbors < 1 ) or self.num_context_neighbors != "default": - raise ValueError("--n-neighbors-context must be either 'default' or an integer > 1") + _log_and_raise_error( + "--n-neighbors-context must be either 'default' or an integer > 1", + error=ValueError, + level=LogLevel.ERROR, + ) def _parse_args() -> _Arguments: From 111465d2aae05e6d6db05b5b754f1cf7157e2af2 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:32:44 -0600 Subject: [PATCH 061/265] fix: drop na values --- main/como/rnaseq_preprocess.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index 718caa11..4ae690b6 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -308,6 +308,7 @@ async def _write_counts_matrix( final_matrix = final_matrix[["ensembl_gene_id", *rna_specific_sample_names]] output_counts_matrix_filepath.parent.mkdir(parents=True, exist_ok=True) + final_matrix.dropna(inplace=True) final_matrix.to_csv(output_counts_matrix_filepath, index=False) logger.success(f"Wrote gene count matrix for '{rna.value}' RNA at '{output_counts_matrix_filepath}'") return final_matrix From 14fb0fac3c58ac02b6ca0e7c7592a10658e66501 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:33:32 -0600 Subject: [PATCH 062/265] feat: async read matrix files --- main/como/rnaseq_preprocess.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index 4ae690b6..442eef1b 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -519,13 +519,15 @@ async def _create_gene_info_file( """ async def read_counts(file: Path) -> list[str]: - data = await asyncio.to_thread(pd.read_csv if file.suffix == ".csv" else sc.read_h5ad, file) - conversion = ( - await ensembl_to_gene_id_and_symbol(ids=data["ensembl_gene_id"].tolist(), taxon=taxon) + data = await _read_file(file, h5ad_as_df=False) + conversion = await ( + ensembl_to_gene_id_and_symbol(ids=data["ensembl_gene_id"].tolist(), taxon=taxon) if isinstance(data, pd.DataFrame) - else await gene_symbol_to_ensembl_and_gene_id(symbols=data.var_names.tolist(), taxon=taxon) + else gene_symbol_to_ensembl_and_gene_id(symbols=data.var_names.tolist(), taxon=taxon) ) - return conversion["entrez_gene_id"].tolist() + + # Remove NA values from entrez_gene_id dataframe column + return conversion["entrez_gene_id"].dropna().tolist() logger.info( "Fetching gene info (this may take 1-5 minutes depending on the number of genes and your internet connection)" From f6326791d5c4c7d335cc0da934d4db018f834c46 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:34:12 -0600 Subject: [PATCH 063/265] refactor: calculate size more pythonically --- main/como/rnaseq_preprocess.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index 442eef1b..1f46b755 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -536,7 +536,7 @@ async def read_counts(file: Path) -> list[str]: gene_data = await MyGene(cache=cache).query(items=list(genes), taxon=taxon, scopes="entrezgene") gene_info: pd.DataFrame = pd.DataFrame( data=None, - columns=pd.Index(data=["ensembl_gene_id", "gene_symbol", "entrez_gene_id", "start_position", "end_position"]), + columns=pd.Index(data=["ensembl_gene_id", "gene_symbol", "entrez_gene_id", "size"]), index=pd.Index(data=range(len(gene_data))), ) for i, data in enumerate(gene_data): @@ -545,15 +545,14 @@ async def read_counts(file: Path) -> list[str]: ensembl_ids = ensembl_ids[0] start_pos = data.get("genomic_pos.start", 0) - start_pos = sum(start_pos) / len(start_pos) if isinstance(start_pos, list) else start_pos + start_pos: int = int(sum(start_pos) / len(start_pos)) if isinstance(start_pos, list) else int(start_pos) end_pos = data.get("genomic_pos.end", 0) - end_pos = sum(end_pos) / len(end_pos) if isinstance(end_pos, list) else end_pos + end_pos: int = int(sum(end_pos) / len(end_pos)) if isinstance(end_pos, list) else int(end_pos) gene_info.at[i, "gene_symbol"] = data.get("symbol", "-") gene_info.at[i, "entrez_gene_id"] = data.get("entrezgene", "-") gene_info.at[i, "ensembl_gene_id"] = ensembl_ids - gene_info.at[i, "start_position"] = start_pos - gene_info.at[i, "end_position"] = end_pos + gene_info.at[i, "size"] = end_pos - start_pos gene_info = gene_info[ ( @@ -562,8 +561,6 @@ async def read_counts(file: Path) -> list[str]: & (gene_info["gene_symbol"] != "-") ) ] - gene_info["size"] = gene_info["end_position"].astype(int) - gene_info["start_position"].astype(int) - gene_info.drop(columns=["start_position", "end_position"], inplace=True) gene_info.sort_values(by="ensembl_gene_id", inplace=True) gene_info.to_csv(output_filepath, index=False) logger.success(f"Gene Info file written at '{output_filepath}'") From 569061679764d0a3fc4166503ad6a9c2103d6757 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:34:37 -0600 Subject: [PATCH 064/265] fix: use better variable for ensembl gene --- main/como/rnaseq_preprocess.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index 1f46b755..5f778fb7 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -540,7 +540,7 @@ async def read_counts(file: Path) -> list[str]: index=pd.Index(data=range(len(gene_data))), ) for i, data in enumerate(gene_data): - ensembl_ids = data.get("ensembl.gene", "-") + ensembl_ids = data.get("genomic_pos.ensemblgene", "-") if isinstance(ensembl_ids, list): ensembl_ids = ensembl_ids[0] From 746099bfc8573ec232e611a0cfc9d304e62c5792 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:34:45 -0600 Subject: [PATCH 065/265] refactor: drop na values --- main/como/rnaseq_preprocess.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index 5f778fb7..9edfb67d 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -562,6 +562,7 @@ async def read_counts(file: Path) -> list[str]: ) ] gene_info.sort_values(by="ensembl_gene_id", inplace=True) + gene_info.dropna(inplace=True) gene_info.to_csv(output_filepath, index=False) logger.success(f"Gene Info file written at '{output_filepath}'") From 132660f5585a8044aad3d63bfb7169aacf67da0d Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:34:54 -0600 Subject: [PATCH 066/265] chore: fix logging message --- main/como/rnaseq_preprocess.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index 9edfb67d..7c076162 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -530,7 +530,8 @@ async def read_counts(file: Path) -> list[str]: return conversion["entrez_gene_id"].dropna().tolist() logger.info( - "Fetching gene info (this may take 1-5 minutes depending on the number of genes and your internet connection)" + "Fetching gene info - " + "this can take up to 5 minutes depending on the number of genes and your internet connection" ) genes = set(chain.from_iterable(await asyncio.gather(*[read_counts(f) for f in counts_matrix_filepaths]))) gene_data = await MyGene(cache=cache).query(items=list(genes), taxon=taxon, scopes="entrezgene") From 1f7d2529a9e56be60df388a4523e9f63363ea3d8 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:35:09 -0600 Subject: [PATCH 067/265] feat: use new LogLevel Enum --- main/como/rnaseq_preprocess.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index 7c076162..f4b4d14c 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -646,7 +646,7 @@ async def rnaseq_preprocess( output_trna_count_matrix_filepath: Path | None = None, output_mrna_count_matrix_filepath: Path | None = None, cache: bool = True, - log_level: LOG_LEVEL = "INFO", + log_level: LogLevel = LogLevel.INFO, log_location: str | TextIOWrapper = sys.stderr, ) -> None: """Preprocesses RNA-seq data for downstream analysis. From 7451732aa438425e6223eec6da739a6905ba92cf Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:35:23 -0600 Subject: [PATCH 068/265] fix: resolve context directory only if provided --- main/como/rnaseq_preprocess.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index f4b4d14c..0846d6d2 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -671,7 +671,9 @@ async def rnaseq_preprocess( _set_up_logging(level=log_level, location=log_location) output_gene_info_filepath = output_gene_info_filepath.resolve() - como_context_dir = como_context_dir.resolve() + + if como_context_dir: + como_context_dir = como_context_dir.resolve() input_matrix_filepath = [i.resolve() for i in _listify(input_matrix_filepath)] if input_matrix_filepath else None output_trna_metadata_filepath = ( output_trna_metadata_filepath.resolve() if output_trna_metadata_filepath else output_trna_metadata_filepath From 58b66e9f84d0a9737cab7c2fce43306544047c42 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:35:44 -0600 Subject: [PATCH 069/265] refactor: import/remove modules --- main/como/rnaseq_gen.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index b8a2f735..9fc6d9e1 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -1,13 +1,13 @@ from __future__ import annotations -import math import multiprocessing +import sys import time from collections import namedtuple +from concurrent.futures import Future, ProcessPoolExecutor, as_completed from dataclasses import dataclass, field from enum import Enum -from functools import partial -from multiprocessing.pool import Pool +from io import TextIOWrapper from pathlib import Path from typing import Callable, NamedTuple @@ -18,16 +18,17 @@ import scanpy as sc import sklearn import sklearn.neighbors -from fast_bioservices.pipeline import ensembl_to_gene_id_and_symbol +from fast_bioservices.pipeline import ensembl_to_gene_id_and_symbol, gene_symbol_to_ensembl_and_gene_id from loguru import logger from pandas import DataFrame from plotly.subplots import make_subplots from scipy.signal import find_peaks from sklearn.neighbors import KernelDensity -from como.data_types import FilteringTechnique, RNAPrepMethod +from como.data_types import FilteringTechnique, LogLevel, PeakIdentificationParameters, RNAType from como.migrations import gene_info_migrations from como.project import Config +from como.utils import _log_and_raise_error, _num_columns, _read_file, _set_up_logging class _FilteringOptions(NamedTuple): From 5c7e3b2cde57baa560cb012b7a638f00d2205ab7 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:42:59 -0600 Subject: [PATCH 070/265] refactor: remove extra read_counts function --- main/como/rnaseq_gen.py | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 9fc6d9e1..e165bebd 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -63,7 +63,11 @@ class _StudyMetrics: def __post_init__(self): for layout in self.layout: if layout not in LayoutMethod: - raise ValueError(f"Layout must be 'paired-end' or 'single-end'; got: {layout}") + _log_and_raise_error( + f"Layout must be 'paired-end' or 'single-end'; got: {layout}", + error=ValueError, + level=LogLevel.ERROR, + ) @property def normalization_matrix(self) -> pd.DataFrame: @@ -133,7 +137,11 @@ def genefilter(data: pd.DataFrame | npt.NDArray, filter_func: Callable[[npt.NDAr :return: A NumPy array of the filtered data. """ if not isinstance(data, (pd.DataFrame, npt.NDArray)): - raise TypeError("Unsupported data type. Must be a Pandas DataFrame or a NumPy array.") + _log_and_raise_error( + f"Unsupported data type. Must be a Pandas DataFrame or a NumPy array, got '{type(data)}'", + error=TypeError, + level=LogLevel.CRITICAL, + ) return ( data.apply(filter_func, axis=1).values @@ -142,22 +150,6 @@ def genefilter(data: pd.DataFrame | npt.NDArray, filter_func: Callable[[npt.NDAr ) -async def _read_counts(path: Path) -> pd.DataFrame: - if path.suffix not in {".csv", ".h5ad"}: - raise ValueError(f"Unknown file extension '{path.suffix}'. Valid options are '.csv' or '.h5ad'.") - - matrix: pd.DataFrame - if path.suffix == ".csv": - logger.debug(f"Reading CSV file at '{path}'") - matrix = pd.read_csv(path, header=0) - elif path.suffix == ".h5ad": - logger.debug(f"Reading h5ad file at '{path}'") - # Make sample names the columns and gene data the index - matrix = sc.read_h5ad(path).to_df().T - - return matrix - - async def _build_matrix_results( *, matrix: pd.DataFrame, From 369b5a13899f54a9af3cb842e710f804648d9ebb Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:43:21 -0600 Subject: [PATCH 071/265] fix: drop na values when building compiling matrix --- main/como/rnaseq_gen.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index e165bebd..24e477c7 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -164,11 +164,12 @@ async def _build_matrix_results( :param taxon: The NCBI Taxon ID :return: A dataclass `ReadMatrixResults` """ + matrix.dropna(inplace=True) conversion = await ensembl_to_gene_id_and_symbol(ids=matrix["ensembl_gene_id"].tolist(), taxon=taxon) conversion["ensembl_gene_id"] = conversion["ensembl_gene_id"].str.split(",") conversion = conversion.explode("ensembl_gene_id") conversion.reset_index(inplace=True, drop=True) - matrix = matrix.merge(conversion, on="ensembl_gene_id", how="left") + matrix = matrix.merge(conversion, on=["ensembl_gene_id", "entrez_gene_id", "gene_symbol"], how="left") # Only include Entrez and Ensembl Gene IDs that are present in `gene_info` matrix["entrez_gene_id"] = matrix["entrez_gene_id"].str.split("//") From e708644cd8f2c06c7112f553be68487ab3044d88 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:43:47 -0600 Subject: [PATCH 072/265] fix: fpkm calculations --- main/como/rnaseq_gen.py | 44 ++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 24e477c7..d0234ec3 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -233,38 +233,46 @@ def calculate_tpm(metrics: NamedMetrics) -> NamedMetrics: return metrics -def _calculate_fpkm(metrics: NamedMetrics) -> NamedMetrics: +def _calculate_fpkm(metrics: NamedMetrics, scale: int = 1e6) -> NamedMetrics: """Calculate the Fragments Per Kilobase of transcript per Million mapped reads (FPKM) for each sample in the metrics dictionary.""" # noqa: E501 for study in metrics: matrix_values = [] for sample in range(metrics[study].num_samples): layout = metrics[study].layout[sample] - count_matrix: npt.NDArray = metrics[study].count_matrix.iloc[:, sample].values - gene_size = metrics[study].gene_sizes - - count_matrix = count_matrix.astype(np.float32) - gene_size = gene_size.astype(np.float32) + count_matrix: npt.NDArray = metrics[study].count_matrix.iloc[:, sample].values.astype(np.float32) + gene_lengths = ( + metrics[study].fragment_lengths[sample].astype(np.float32) + if layout == LayoutMethod.paired_end + else metrics[study].gene_sizes.astype(np.float32) + ) + gene_lengths_kb = gene_lengths / 1000.0 match layout: case LayoutMethod.paired_end: # FPKM - mean_fragment_lengths = metrics[study].fragment_lengths[sample] - # Ensure non-negative value - effective_length = [max(1e-9, size - (mean_fragment_lengths + 1)) for size in gene_size] - n = count_matrix.sum() - fpkm = ((count_matrix + 1) * 1e9) / (np.array(effective_length) * n) - matrix_values.append(fpkm) + total_fragments = count_matrix.sum(axis=0) + counts_per_million = total_fragments / scale + fragments_per_kilobase = count_matrix / gene_lengths_kb[:, np.newaxis] + fragments_per_kilobase_million = fragments_per_kilobase / counts_per_million + matrix_values.append(fragments_per_kilobase_million) case LayoutMethod.single_end: # RPKM - # Add a pseudocount before log to ensure log(0) does not happen - rate = np.log(count_matrix + 1) - np.log(gene_size) - exp_rate = np.exp(rate - np.log(np.sum(count_matrix)) + np.log(1e9)) - matrix_values.append(exp_rate) + reads_per_kilobase = count_matrix / gene_lengths_kb[: np.newaxis] + total_reads = count_matrix.sum(axis=0) + counts_per_million = total_reads / scale + reads_per_kilobase_million = reads_per_kilobase / counts_per_million + matrix_values.append(reads_per_kilobase_million) case _: - raise ValueError("Invalid normalization method specified") + _log_and_raise_error( + ( + f"Invalid normalization method specified ''. " + f"Must be one of '{LayoutMethod.paired_end.value}' or '{LayoutMethod.single_end.value}'." + ), + error=ValueError, + level=LogLevel.ERROR, + ) fpkm_matrix = pd.DataFrame(matrix_values).T # Transpose is needed because values were appended as rows fpkm_matrix = fpkm_matrix[~pd.isna(fpkm_matrix)] metrics[study].normalization_matrix = fpkm_matrix - metrics[study].normalization_matrix.columns = metrics[study].count_matrix.columns return metrics From 002c7053f3a9414b210b97541dcfa84439ca612d Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:43:58 -0600 Subject: [PATCH 073/265] style: ruff formatting --- main/como/rnaseq_gen.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index d0234ec3..97c81be8 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -278,7 +278,12 @@ def _calculate_fpkm(metrics: NamedMetrics, scale: int = 1e6) -> NamedMetrics: return metrics -def _zfpkm_calculation(row: pd.Series, kernel: KernelDensity, peak_parameters: tuple[float, float]) -> _ZFPKMResult: +# def _zfpkm_calculation(row: pd.Series, kernel: KernelDensity, peak_parameters: tuple[float, float]) -> _ZFPKMResult: +def _zfpkm_calculation( + column: pd.Series, + peak_parameters: PeakIdentificationParameters, + bandwidth: int = 0.5, +) -> _ZFPKMResult: """Log2 Transformations. Stabilize the variance in the data to make the distribution more symmetric; this is helpful for Gaussian fitting From f8bf9983bfb008c1e9192c71f01104553912c1f0 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:44:07 -0600 Subject: [PATCH 074/265] style: fix docstring --- main/como/rnaseq_gen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 97c81be8..4367001e 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -324,7 +324,7 @@ def _zfpkm_calculation( - Higher zFPKM values indicate higher expression levels relative to the "inactive" peak - A zFPKM value of 0 represents the mean of the "inactive" distribution - Research shows that a zFPKM value of -3 or greater can be used as - a threshold for calling a gene as "expressed" + a threshold for calling a gene as "active" and/or "expressed" : https://doi.org/10.1186/1471-2164-14-778 """ row_log2: npt.NDArray = np.log2(row + 1) From e7f65e09c699e3abff3db65f12e6847237e9dbd0 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:44:57 -0600 Subject: [PATCH 075/265] fix: zfpkm calculations Use column values instead of row values --- main/como/rnaseq_gen.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 4367001e..7935f51f 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -327,14 +327,12 @@ def _zfpkm_calculation( a threshold for calling a gene as "active" and/or "expressed" : https://doi.org/10.1186/1471-2164-14-778 """ - row_log2: npt.NDArray = np.log2(row + 1) - row_log2 = np.nan_to_num(row_log2, nan=0) - refit: KernelDensity = kernel.fit(row_log2.reshape(-1, 1)) # type: ignore + values = column.values + refit: KernelDensity = KernelDensity(kernel="gaussian", bandwidth=bandwidth).fit(values.reshape(-1, 1)) # type: ignore - # kde: KernelDensity = KernelDensity(kernel="gaussian", bandwidth=bandwidth).fit(row_log2.reshape(-1, 1)) - x_range = np.linspace(row_log2.min(), row_log2.max(), 1000) + x_range = np.linspace(values.min(), values.max(), 2000) density = np.exp(refit.score_samples(x_range.reshape(-1, 1))) - peaks, _ = find_peaks(density, height=peak_parameters[0], distance=peak_parameters[1]) + peaks, _ = find_peaks(density, height=peak_parameters.height, distance=peak_parameters.distance) peak_positions = x_range[peaks] mu = 0 @@ -344,9 +342,9 @@ def _zfpkm_calculation( if len(peaks) != 0: mu = peak_positions.max() max_fpkm = density[peaks[np.argmax(peak_positions)]] - u = row_log2[row_log2 > mu].mean() + u = values[values > mu].mean() stddev = (u - mu) * np.sqrt(np.pi / 2) - zfpkm = pd.Series((row_log2 - mu) / stddev, dtype=np.float32, name=row.name) + zfpkm = pd.Series((values - mu) / stddev, dtype=np.float32, name=column.name) return _ZFPKMResult(zfpkm=zfpkm, density=Density(x_range, density), mu=mu, std_dev=stddev, max_fpkm=max_fpkm) @@ -365,13 +363,15 @@ def zfpkm_transform( ) update_every_percent /= 100 - total_rows = len(fpkm_df) - update_per_step: int = int(np.ceil(total_rows * update_every_percent)) - cores = max(min(multiprocessing.cpu_count() - 2, total_rows), 1) # Get at least 1 core and at most cpu_count() - 2 + total_samples = _num_columns(fpkm_df) + update_per_step: int = int(np.ceil(total_samples * update_every_percent)) + + # Get at least 1 core and at most cpu_count() - 2 + cores = max(min(multiprocessing.cpu_count() - 2, total_samples), 1) logger.debug( - f"zFPKM transforming {total_rows:,} gene(s) across {len(fpkm_df.columns)} sample(s) using {cores} cores" + f"zFPKM transforming {len(fpkm_df.columns)} sample(s) " + f"containing {len(fpkm_df):,} genes(s) using {cores} core(s)" ) - logger.debug(f"Will update every {update_per_step:,} steps (~{update_every_percent:.1%} of {total_rows:,})") with Pool(processes=cores) as pool: kernel = KernelDensity(kernel="gaussian", bandwidth=bandwidth) From 93e98442a929458e1af7f5d18bf6c906d7f91b3a Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:45:22 -0600 Subject: [PATCH 076/265] feat: use concurrent.futures for easier processing --- main/como/rnaseq_gen.py | 47 ++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 7935f51f..1d541c69 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -372,44 +372,43 @@ def zfpkm_transform( f"zFPKM transforming {len(fpkm_df.columns)} sample(s) " f"containing {len(fpkm_df):,} genes(s) using {cores} core(s)" ) - - with Pool(processes=cores) as pool: - kernel = KernelDensity(kernel="gaussian", bandwidth=bandwidth) - chunksize = int(math.ceil(len(fpkm_df.columns) / (4 * cores))) - partial_func = partial(_zfpkm_calculation, kernel=kernel, peak_parameters=peak_parameters) - chunk_time = time.time() - start_time = time.time() - log_padding = len(str(f"{total_rows:,}")) - - zfpkm_series: list[pd.Series | None] = [None] * total_rows - results: dict[str, _ZFPKMResult] = {} - result: _ZFPKMResult - for i, result in enumerate( - pool.imap( - partial_func, - (row for _, row in fpkm_df.iterrows()), - chunksize=chunksize, + logger.debug(f"Will update every {update_per_step:,} steps (~{update_every_percent:.1%} of {total_samples:,})") + + chunk_time = time.time() + start_time = time.time() + log_padding = len(str(f"{total_samples:,}")) + zfpkm_series: list[pd.Series | None] = [None] * total_samples + results: dict[str, _ZFPKMResult] = {} + + with ProcessPoolExecutor(max_workers=cores) as pool: + futures: list[Future[_ZFPKMResult]] = [ + pool.submit( + _zfpkm_calculation, + column=fpkm_df[column], + peak_parameters=peak_parameters, + bandwidth=bandwidth, ) - ): + for column in fpkm_df + ] + for i, future in enumerate(as_completed(futures)): + result = future.result() key = str(result.zfpkm.name) results[key] = result zfpkm_series[i] = result.zfpkm - # show updates every X% and at the end, but skip on first iteration - if i != 0 and (i % update_per_step == 0 or i >= total_rows): + if i != 0 and ((i + 1) % update_per_step == 0 or (i + 1) == total_samples): current_time = time.time() chunk = current_time - chunk_time total_time = current_time - start_time - chunk_num = f"{i:,}" + chunk_num = f"{i + 1:,}" logger.debug( - f"Processed {chunk_num:>{log_padding}} of {total_rows:,} - " + f"Processed {chunk_num:>{log_padding}} of {total_samples:,} - " f"chunk took {chunk:.1f} seconds - " f"running for {total_time:.1f} seconds" ) chunk_time = current_time - zfpkm_df = pd.concat(zfpkm_series, axis=1) - + zfpkm_df = pd.DataFrame({series.name: series for series in zfpkm_series}, index=fpkm_df.index) return results, zfpkm_df From d6cb67705310d850562d1b1b482f5f9f4cc3051d Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:45:34 -0600 Subject: [PATCH 077/265] feat: allow setting bandwidth and peak parameters --- main/como/rnaseq_gen.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 1d541c69..913462c6 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -351,8 +351,8 @@ def _zfpkm_calculation( def zfpkm_transform( fpkm_df: pd.DataFrame, - bandwidth: int = 0.5, - peak_parameters: tuple[float, float] = (0.02, 1.0), + peak_parameters: PeakIdentificationParameters, + bandwidth: int, update_every_percent: float = 0.1, ) -> tuple[dict[str, _ZFPKMResult], DataFrame]: """Perform zFPKM calculation/transformation.""" From b2e5fe62231fbfd4286c3d33359f390c4fd41f73 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:45:46 -0600 Subject: [PATCH 078/265] style: ruff whitespace fixes --- main/como/rnaseq_gen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 913462c6..72917d9d 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -443,8 +443,8 @@ def zfpkm_plot(results, *, plot_xfloor: int = -4, subplot_titles: bool = True): ) mega_df = pd.concat(to_concat, ignore_index=True) mega_df.columns = pd.Series(data=["sample_name", "log2fpkm", "fpkm_density", "fitted_density_scaled"]) - mega_df = mega_df.melt(id_vars=["log2fpkm", "sample_name"], var_name="source", value_name="density") + subplot_titles = list(results.keys()) if subplot_titles else None fig = make_subplots( rows=len(results), From 720543f7522421a6f62c4797be85c02c0cf0672f Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:46:13 -0600 Subject: [PATCH 079/265] refactor: more efficient zfpkm plotting --- main/como/rnaseq_gen.py | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 72917d9d..63e4fc04 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -453,16 +453,35 @@ def zfpkm_plot(results, *, plot_xfloor: int = -4, subplot_titles: bool = True): vertical_spacing=min(0.05, (1 / (len(results) - 1))), ) - for i, (name, group) in enumerate(mega_df.groupby("sample_name"), start=1): - fig.add_trace( - trace=go.Scatter(x=group["log2fpkm"], y=group["density"], mode="lines", name=name, legendgroup=name), - row=i, - col=1, - ) - fig.update_xaxes(title_text="log2(FPKM)", range=[plot_xfloor, max(group["log2fpkm"].tolist())], row=i, col=1) + for i, sample_name in enumerate(results, start=1): + sample_data = mega_df[mega_df["sample_name"] == sample_name] + traces = [] + for source_type in sample_data["source"].unique(): + group = sample_data[sample_data["source"] == source_type] + traces.append( + go.Scatter( + x=group["log2fpkm"], + y=group["density"], + mode="lines", + name=source_type, + legendgroup=source_type, + ) + ) + fig.add_traces(traces, rows=i, cols=1) + fig.update_xaxes(title_text="log2(FPKM)", range=[plot_xfloor, sample_data["log2fpkm"].max()], row=i, col=1) fig.update_yaxes(title_text="density [scaled]", row=i, col=1) fig.update_layout(legend_tracegroupgap=0) + # for i, (name, group) in enumerate(mega_df.groupby("sample_name"), start=1): + # fig.add_trace( + # trace=go.Scatter(x=group["log2fpkm"], y=group["density"], mode="lines", name=name, legendgroup=name), + # row=i, + # col=1, + # ) + # fig.update_xaxes(title_text="log2(FPKM)", range=[plot_xfloor, max(group["log2fpkm"].tolist())], row=i, col=1) + # fig.update_yaxes(title_text="density [scaled]", row=i, col=1) + # fig.update_layout(legend_tracegroupgap=0) + fig.update_layout(height=600 * len(results), width=1000, title_text="zFPKM Plots", showlegend=True) fig.write_image("zfpkm_plot.png") From 1daa66e5e8c319f66e27c66b1aea2cb12f2a3a7a Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:47:18 -0600 Subject: [PATCH 080/265] feat: use new RNAType Enum --- main/como/rnaseq_gen.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 63e4fc04..427237d2 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -502,7 +502,7 @@ def cpm_filter( context_name: str, metrics: NamedMetrics, filtering_options: _FilteringOptions, - prep: RNAPrepMethod, + prep: RNAType, ) -> NamedMetrics: """Apply Counts Per Million (CPM) filtering to the count matrix for a given sample.""" config = Config() @@ -632,7 +632,7 @@ def filter_counts( metrics: NamedMetrics, technique: FilteringTechnique, filtering_options: _FilteringOptions, - prep: RNAPrepMethod, + prep: RNAType, ) -> NamedMetrics: """Filter the count matrix based on the specified technique.""" match technique: @@ -655,7 +655,7 @@ async def _save_rnaseq_tests( rnaseq_matrix: pd.DataFrame, metadata_df: pd.DataFrame, gene_info_df: pd.DataFrame, - prep: RNAPrepMethod, + prep: RNAType, taxon: int, replicate_ratio: float, batch_ratio: float, @@ -753,7 +753,7 @@ async def rnaseq_gen( context_name: str, input_rnaseq_filepath: Path, input_gene_info_filepath: Path, - prep: RNAPrepMethod, + prep: RNAType, taxon_id: int, output_boolean_activity_filepath: Path, output_zscore_normalization_filepath: Path, From 0b005b768dd8e328848ed4df482b304b730341b6 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:47:29 -0600 Subject: [PATCH 081/265] fix: drop na values --- main/como/rnaseq_gen.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 427237d2..d9d8234c 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -527,6 +527,7 @@ def cpm_filter( counts_per_million: pd.DataFrame = (counts / library_size) * 1_000_000 counts_per_million.insert(0, "entrez_gene_ids", pd.Series(entrez_ids)) logger.debug(f"Writing CPM matrix to {output_filepath}") + counts_per_million.dropna(inplace=True) counts_per_million.to_csv(output_filepath, index=False) # TODO: Counts per million is adding ~61,500 columns (equal to the number of genes) for some reason. From cb6e995e7f44551e7a3e5f911bacb66937ea708c Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:47:56 -0600 Subject: [PATCH 082/265] refactor: provide bandwidth and peak parameters --- main/como/rnaseq_gen.py | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index d9d8234c..8859a9d7 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -594,7 +594,15 @@ def tpm_quantile_filter(*, metrics: NamedMetrics, filtering_options: _FilteringO return metrics -def zfpkm_filter(*, metrics: NamedMetrics, filtering_options: _FilteringOptions, calculate_fpkm: bool) -> NamedMetrics: +def zfpkm_filter( + *, + metrics: NamedMetrics, + filtering_options: _FilteringOptions, + calculate_fpkm: bool, + force_zfpkm_plot: bool, + peak_parameters: PeakIdentificationParameters, + bandwidth: int, +) -> NamedMetrics: """Apply zFPKM filtering to the FPKM matrix for a given sample.""" min_sample_expression = filtering_options.replicate_ratio high_confidence_sample_expression = filtering_options.high_replicate_ratio @@ -605,12 +613,19 @@ def zfpkm_filter(*, metrics: NamedMetrics, filtering_options: _FilteringOptions, for metric in metrics.values(): # if fpkm was not calculated, the normalization matrix will be empty; collect the count matrix instead matrix = metric.count_matrix if metric.normalization_matrix.empty else metric.normalization_matrix - matrix = matrix[matrix.sum(axis=1) > 0] # remove rows (genes) that have no counts + matrix = matrix[matrix.sum(axis=1) > 0] # remove rows (genes) that have no counts across all samples minimums = matrix == 0 - results, zfpkm_df = zfpkm_transform(matrix) + results, zfpkm_df = zfpkm_transform(matrix, peak_parameters=peak_parameters, bandwidth=bandwidth) zfpkm_df[minimums] = -4 - zfpkm_plot(results) + + if len(results) > 10 and not force_zfpkm_plot: + logger.warning( + "Not plotting zFPKM results because more than 10 plots would be created. " + "If you would like to plot them anyway, set 'force_zfpkm_plot' to True" + ) + else: + zfpkm_plot(results) # determine which genes are expressed min_samples = round(min_sample_expression * len(zfpkm_df.columns)) From 8c16d943ba65876eeabc5254a774da789303b2ef Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:49:20 -0600 Subject: [PATCH 083/265] feat: allow force-plotting zfpkm If more than ~10 samples exist, zFPKM plotting will not be done for efficiency sake. `force_zfpkm_plot` can be provided to force the plots to be made anyway --- main/como/rnaseq_gen.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 8859a9d7..43720216 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -649,6 +649,9 @@ def filter_counts( technique: FilteringTechnique, filtering_options: _FilteringOptions, prep: RNAType, + force_zfpkm_plot: bool, + peak_parameters: PeakIdentificationParameters, + bandwidth: int, ) -> NamedMetrics: """Filter the count matrix based on the specified technique.""" match technique: @@ -679,8 +682,11 @@ async def _save_rnaseq_tests( high_batch_ratio: float, technique: FilteringTechnique, cut_off: int | float, + force_zfpkm_plot: bool, output_boolean_activity_filepath: Path, output_zscore_normalization_filepath: Path, + peak_parameters: PeakIdentificationParameters, + bandwidth: int, ): """Save the results of the RNA-Seq tests to a CSV file.""" filtering_options = _FilteringOptions( @@ -706,6 +712,9 @@ async def _save_rnaseq_tests( technique=technique, filtering_options=filtering_options, prep=prep, + force_zfpkm_plot=force_zfpkm_plot, + peak_parameters=peak_parameters, + bandwidth=bandwidth, ) merged_zscore_df = pd.DataFrame() @@ -779,7 +788,11 @@ async def rnaseq_gen( batch_ratio: float = 0.5, high_batch_ratio: float = 1.0, technique: FilteringTechnique | str = FilteringTechnique.tpm, + zfpkm_peak_height: float = 0.02, + zfpkm_peak_distance: float = 1.0, + zfpkm_bandwidth: int = 1, cutoff: int | float | None = None, + force_zfpkm_plot: bool = False, ) -> None: """Generate a list of active and high-confidence genes from a gene count matrix. @@ -803,7 +816,13 @@ async def rnaseq_gen( :param high_batch_ratio: The percentage of batches that a gene must appear in for a gene to be marked "highly confident" in its expression :param technique: The filtering technique to use + :param zfpkm_peak_height: The height of the zFPKM peak + :param zfpkm_peak_distance: The distance of the zFPKM peak + :param zfpkm_bandwidth: The bandwidth of the zFPKM :param cutoff: The cutoff value to use for the provided filtering technique + :param force_zfpkm_plot: If too many samples exist, should plotting be done anyway? + :param log_level: The level of logging to output + :param log_location: The location to write logs to :return: None """ technique = ( From 97c7d1db7fd5a32702e6730ed87547592a22e54c Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:50:23 -0600 Subject: [PATCH 084/265] refactor: rename FilteringTechnique constants --- main/como/rnaseq_gen.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 43720216..4930a2ae 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -655,11 +655,11 @@ def filter_counts( ) -> NamedMetrics: """Filter the count matrix based on the specified technique.""" match technique: - case FilteringTechnique.cpm: + case FilteringTechnique.CPM: return cpm_filter( context_name=context_name, metrics=metrics, filtering_options=filtering_options, prep=prep ) - case FilteringTechnique.tpm: + case FilteringTechnique.TPM: return tpm_quantile_filter(metrics=metrics, filtering_options=filtering_options) case FilteringTechnique.zfpkm: return zfpkm_filter(metrics=metrics, filtering_options=filtering_options, calculate_fpkm=True) @@ -787,7 +787,7 @@ async def rnaseq_gen( high_replicate_ratio: float = 1.0, batch_ratio: float = 0.5, high_batch_ratio: float = 1.0, - technique: FilteringTechnique | str = FilteringTechnique.tpm, + technique: FilteringTechnique | str = FilteringTechnique.ZFPKM, zfpkm_peak_height: float = 0.02, zfpkm_peak_distance: float = 1.0, zfpkm_bandwidth: int = 1, @@ -830,18 +830,18 @@ async def rnaseq_gen( ) match technique: - case FilteringTechnique.tpm: + case FilteringTechnique.TPM: cutoff = cutoff or 25 if cutoff < 1 or cutoff > 100: raise ValueError("Quantile must be between 1 - 100") - case FilteringTechnique.cpm: + case FilteringTechnique.CPM: if cutoff and cutoff < 0: raise ValueError("Cutoff must be greater than 0") elif cutoff: cutoff = "default" - case FilteringTechnique.zfpkm: + case FilteringTechnique.ZFPKM | FilteringTechnique.UMI: cutoff = cutoff or -3 case FilteringTechnique.umi: pass @@ -851,8 +851,8 @@ async def rnaseq_gen( if not input_rnaseq_filepath.exists(): raise FileNotFoundError(f"Input RNA-seq file not found! Searching for: '{input_rnaseq_filepath}'") - if prep == RNAPrepMethod.SCRNA: technique = FilteringTechnique.umi + if prep == RNAType.SCRNA and technique.value.lower() != FilteringTechnique.UMI.value.lower(): logger.warning( "Single cell filtration does not normalize and assumes " "gene counts are counted with Unique Molecular Identifiers (UMIs). " From b67cd842c7e03d7cb5c77ea8d210e48a6a15c317 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:51:33 -0600 Subject: [PATCH 085/265] style: ruff whitespace and log message formatting --- main/como/rnaseq_gen.py | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 4930a2ae..6a1b0bed 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -661,12 +661,31 @@ def filter_counts( ) case FilteringTechnique.TPM: return tpm_quantile_filter(metrics=metrics, filtering_options=filtering_options) - case FilteringTechnique.zfpkm: - return zfpkm_filter(metrics=metrics, filtering_options=filtering_options, calculate_fpkm=True) - case FilteringTechnique.umi: - return zfpkm_filter(metrics=metrics, filtering_options=filtering_options, calculate_fpkm=False) + case FilteringTechnique.ZFPKM: + return zfpkm_filter( + metrics=metrics, + filtering_options=filtering_options, + calculate_fpkm=True, + force_zfpkm_plot=force_zfpkm_plot, + peak_parameters=peak_parameters, + bandwidth=bandwidth, + ) + case FilteringTechnique.UMI: + # UMI filtering is the same as zFPKM filtering without calculating FPKM + return zfpkm_filter( + metrics=metrics, + filtering_options=filtering_options, + calculate_fpkm=False, + force_zfpkm_plot=force_zfpkm_plot, + peak_parameters=peak_parameters, + bandwidth=bandwidth, + ) case _: - raise ValueError(f"Technique must be one of {FilteringTechnique}") + _log_and_raise_error( + f"Technique must be one of {FilteringTechnique}, got '{technique.value}'", + error=ValueError, + level=LogLevel.ERROR, + ) async def _save_rnaseq_tests( @@ -760,7 +779,8 @@ async def _save_rnaseq_tests( boolean_matrix.to_csv(output_boolean_activity_filepath, index=False) logger.info( - f"{context_name} - Found {expressed_count} expressed and {high_confidence_count} confidently expressed genes" + f"{context_name} - Found {expressed_count} expressed genes, " + f"{high_confidence_count} of which are confidently expressed" ) logger.success(f"Wrote boolean matrix to {output_boolean_activity_filepath}") @@ -843,8 +863,6 @@ async def rnaseq_gen( case FilteringTechnique.ZFPKM | FilteringTechnique.UMI: cutoff = cutoff or -3 - case FilteringTechnique.umi: - pass case _: raise ValueError(f"Technique must be one of {FilteringTechnique}") @@ -855,8 +873,9 @@ async def rnaseq_gen( if prep == RNAType.SCRNA and technique.value.lower() != FilteringTechnique.UMI.value.lower(): logger.warning( "Single cell filtration does not normalize and assumes " - "gene counts are counted with Unique Molecular Identifiers (UMIs). " - "Setting filtering technique to UMI now." + "genes are counted with Unique Molecular Identifiers (UMIs). " + f"Switching filtering technique from '{technique.value}' to '{FilteringTechnique.UMI.value}'." + ) ) logger.debug(f"Starting '{context_name}'") From 638de62ff1d84fa6debbe43dce166c3fe71b80f8 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:52:20 -0600 Subject: [PATCH 086/265] refactor: use _process, not _save_rnaseq_tests Makes more sense as to what is actually happening when calling this internal function --- main/como/rnaseq_gen.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 6a1b0bed..d61d970d 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -688,7 +688,7 @@ def filter_counts( ) -async def _save_rnaseq_tests( +async def _process( context_name: str, rnaseq_matrix: pd.DataFrame, metadata_df: pd.DataFrame, @@ -885,7 +885,7 @@ async def rnaseq_gen( if isinstance(input_metadata_filepath_or_df, pd.DataFrame) else await _create_metadata_df(input_metadata_filepath_or_df) ) - await _save_rnaseq_tests( + await _process( context_name=context_name, rnaseq_matrix=await _read_counts(input_rnaseq_filepath), metadata_df=metadata_df, From ba852371c2e07bef44881742d72335ca248ba2b6 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:52:43 -0600 Subject: [PATCH 087/265] refactor: provide path to rnaseq matrix --- main/como/rnaseq_gen.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index d61d970d..c4050a4d 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -690,7 +690,7 @@ def filter_counts( async def _process( context_name: str, - rnaseq_matrix: pd.DataFrame, + rnaseq_matrix_filepath: Path, metadata_df: pd.DataFrame, gene_info_df: pd.DataFrame, prep: RNAType, @@ -887,7 +887,7 @@ async def rnaseq_gen( ) await _process( context_name=context_name, - rnaseq_matrix=await _read_counts(input_rnaseq_filepath), + rnaseq_matrix_filepath=input_rnaseq_filepath, metadata_df=metadata_df, gene_info_df=pd.read_csv(input_gene_info_filepath), prep=prep, From 681e871f17e2238df3e4b3acaba7571f4f3024c2 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:52:56 -0600 Subject: [PATCH 088/265] refactor: process provided rnaseq matrix --- main/como/rnaseq_gen.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index c4050a4d..985292a3 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -708,6 +708,17 @@ async def _process( bandwidth: int, ): """Save the results of the RNA-Seq tests to a CSV file.""" + output_boolean_activity_filepath.parent.mkdir(parents=True, exist_ok=True) + + rnaseq_matrix: pd.DataFrame = await _read_file(rnaseq_matrix_filepath) + if rnaseq_matrix_filepath.suffix == ".h5ad": + conversion = await gene_symbol_to_ensembl_and_gene_id( + symbols=rnaseq_matrix["gene_symbol"].tolist(), taxon=taxon + ) + conversion.reset_index(inplace=True) + rnaseq_matrix = rnaseq_matrix.merge(conversion, how="left", on="gene_symbol") + rnaseq_matrix.replace(to_replace=pd.NA, value="-") + filtering_options = _FilteringOptions( replicate_ratio=replicate_ratio, batch_ratio=batch_ratio, From f4d6be9d19a1e2f591ecf40f961ff312390a534d Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:53:32 -0600 Subject: [PATCH 089/265] fix: proper check if dataframe is empty/None --- main/como/rnaseq_gen.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 985292a3..a72e7f82 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -753,12 +753,12 @@ async def _process( for metric in metrics.values(): expressed_genes.extend(metric.entrez_gene_ids) top_genes.extend(metric.high_confidence_entrez_gene_ids) - if metric.normalization_matrix is not None: + if not metric.normalization_matrix.empty: merged_zscore_df = ( - metric.normalization_matrix + metric.z_score_matrix if merged_zscore_df.empty else pd.concat( - [merged_zscore_df, metric.normalization_matrix], + [merged_zscore_df, metric.z_score_matrix], axis=1, ) ) From 54cd8ac27f9cb662296c72bd1df07a7f9637edb2 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:53:49 -0600 Subject: [PATCH 090/265] fix: only write normalized matrix if data exists --- main/como/rnaseq_gen.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index a72e7f82..6e0f334b 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -762,9 +762,18 @@ async def _process( axis=1, ) ) - merged_zscore_df.index = pd.Series(entrez_gene_ids, name="entrez_gene_id") - merged_zscore_df.to_csv(output_zscore_normalization_filepath, index=True) - logger.success(f"Wrote z-score normalization matrix to {output_zscore_normalization_filepath}") + + # If any of the normalization metrics are not empty, write the normalized metrics to disk + if not all(metric.normalization_matrix.empty for metric in metrics.values()): + merged_zscore_df.index = pd.Series(entrez_gene_ids, name="entrez_gene_id") + merged_zscore_df.dropna(inplace=True) + merged_zscore_df.to_csv(output_zscore_normalization_filepath, index=True) + logger.success(f"Wrote z-score normalization matrix to {output_zscore_normalization_filepath}") + else: + logger.warning( + "Not writing z-score normalization matrix because no normalization matrices exist. " + "This is expected if you are using UMI filtering." + ) expression_frequency = pd.Series(expressed_genes).value_counts() expression_df = pd.DataFrame( From ea9654d8c7be772d508d4835652e946e1d373468 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:54:04 -0600 Subject: [PATCH 091/265] fix: proper calculation of high confidence genes --- main/como/rnaseq_gen.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 6e0f334b..8d452c0b 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -795,8 +795,9 @@ async def _process( boolean_matrix.loc[gene, "high"] = 1 expressed_count = len(boolean_matrix[boolean_matrix["expressed"] == 1]) - high_confidence_count = len(boolean_matrix[boolean_matrix["high"] == 1]) + high_confidence_count = len(boolean_matrix[boolean_matrix["high"] == 1]) - expressed_count + boolean_matrix.dropna(subset="entrez_gene_id", inplace=True) boolean_matrix.to_csv(output_boolean_activity_filepath, index=False) logger.info( f"{context_name} - Found {expressed_count} expressed genes, " From e663406a7fac8f8f5e2e2280b716d983351b52e7 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:54:15 -0600 Subject: [PATCH 092/265] refactor: remove internal _create_metadata_df func --- main/como/rnaseq_gen.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 8d452c0b..265b6383 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -806,15 +806,6 @@ async def _process( logger.success(f"Wrote boolean matrix to {output_boolean_activity_filepath}") -async def _create_metadata_df(path: Path) -> pd.DataFrame: - if path.suffix not in {".xls", ".xlsx"}: - raise ValueError( - f"Expected an excel file with extension of '.xlsx' or '.xls', got '{path.suffix}'. " - f"Attempted to process: {path}" - ) - return pd.read_excel(path) - - async def rnaseq_gen( context_name: str, input_rnaseq_filepath: Path, From fda629ec5a455e5786ed9b405c41a23c2c897d8f Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:54:36 -0600 Subject: [PATCH 093/265] refactor: proper usage of _set_up_logging function --- main/como/rnaseq_gen.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 265b6383..507e3463 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -825,6 +825,8 @@ async def rnaseq_gen( zfpkm_bandwidth: int = 1, cutoff: int | float | None = None, force_zfpkm_plot: bool = False, + log_level: LogLevel = LogLevel.INFO, + log_location: str | TextIOWrapper = sys.stderr, ) -> None: """Generate a list of active and high-confidence genes from a gene count matrix. @@ -857,10 +859,9 @@ async def rnaseq_gen( :param log_location: The location to write logs to :return: None """ - technique = ( - FilteringTechnique.from_string(str(technique.lower())) if isinstance(technique, (str, int)) else technique - ) + _set_up_logging(level=log_level, location=log_location) + technique = FilteringTechnique(technique) if isinstance(technique, str) else technique match technique: case FilteringTechnique.TPM: cutoff = cutoff or 25 From 59f7f955c02d84fdd3c47cefa37057bd513769d1 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:55:03 -0600 Subject: [PATCH 094/265] fix: proper usage of _log_and_raise_error function --- main/como/rnaseq_gen.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 507e3463..adab17b0 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -866,23 +866,38 @@ async def rnaseq_gen( case FilteringTechnique.TPM: cutoff = cutoff or 25 if cutoff < 1 or cutoff > 100: - raise ValueError("Quantile must be between 1 - 100") + _log_and_raise_error( + "Quantile must be between 1 - 100", + error=ValueError, + level=LogLevel.ERROR, + ) case FilteringTechnique.CPM: if cutoff and cutoff < 0: - raise ValueError("Cutoff must be greater than 0") + _log_and_raise_error( + "Cutoff must be greater than or equal to 0", + error=ValueError, + level=LogLevel.ERROR, + ) elif cutoff: cutoff = "default" case FilteringTechnique.ZFPKM | FilteringTechnique.UMI: cutoff = cutoff or -3 case _: - raise ValueError(f"Technique must be one of {FilteringTechnique}") + _log_and_raise_error( + f"Technique must be one of {','.join(FilteringTechnique)}. Got: {technique.value}", + error=ValueError, + level=LogLevel.ERROR, + ) if not input_rnaseq_filepath.exists(): - raise FileNotFoundError(f"Input RNA-seq file not found! Searching for: '{input_rnaseq_filepath}'") + _log_and_raise_error( + f"Input RNA-seq file not found! Searching for: '{input_rnaseq_filepath}'", + error=FileNotFoundError, + level=LogLevel.ERROR, + ) - technique = FilteringTechnique.umi if prep == RNAType.SCRNA and technique.value.lower() != FilteringTechnique.UMI.value.lower(): logger.warning( "Single cell filtration does not normalize and assumes " From 3b63b7d2bfd7e89e51e2fa70b1f9a190b34b7457 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:55:20 -0600 Subject: [PATCH 095/265] refactor: proper processing of metadata --- main/como/rnaseq_gen.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index adab17b0..58f209a4 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -904,6 +904,33 @@ async def rnaseq_gen( "genes are counted with Unique Molecular Identifiers (UMIs). " f"Switching filtering technique from '{technique.value}' to '{FilteringTechnique.UMI.value}'." ) + technique = FilteringTechnique.UMI + + if isinstance(input_metadata_filepath_or_df, pd.DataFrame): + metadata_df = input_metadata_filepath_or_df + elif isinstance(input_metadata_filepath_or_df, Path): + if input_metadata_filepath_or_df.suffix not in {".xlsx", ".xls"}: + _log_and_raise_error( + ( + f"Expected an excel file with extension of '.xlsx' or '.xls', " + f"got '{input_metadata_filepath_or_df.suffix}'." + ), + error=ValueError, + level=LogLevel.ERROR, + ) + if not input_metadata_filepath_or_df.exists(): + _log_and_raise_error( + f"Input metadata file not found! Searching for: '{input_metadata_filepath_or_df}'", + error=FileNotFoundError, + level=LogLevel.ERROR, + ) + + metadata_df = pd.read_excel(input_metadata_filepath_or_df) + else: + _log_and_raise_error( + f"Expected a pandas DataFrame or Path object as metadata, got '{type(input_metadata_filepath_or_df)}'", + error=TypeError, + level=LogLevel.ERROR, ) logger.debug(f"Starting '{context_name}'") From 0ff2eb7227e185b14932f3a016d4b1ce2dc2aa58 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:55:42 -0600 Subject: [PATCH 096/265] refactor: move logic to out of main function --- main/como/rnaseq_gen.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 58f209a4..3b602c36 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -934,12 +934,6 @@ async def rnaseq_gen( ) logger.debug(f"Starting '{context_name}'") - output_boolean_activity_filepath.parent.mkdir(parents=True, exist_ok=True) - metadata_df = ( - input_metadata_filepath_or_df - if isinstance(input_metadata_filepath_or_df, pd.DataFrame) - else await _create_metadata_df(input_metadata_filepath_or_df) - ) await _process( context_name=context_name, rnaseq_matrix_filepath=input_rnaseq_filepath, From 777064382cb22fb50b75fd652db6843fdc671561 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:55:54 -0600 Subject: [PATCH 097/265] fix: add proper function parameters --- main/como/rnaseq_gen.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 3b602c36..8fe2780a 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -938,7 +938,7 @@ async def rnaseq_gen( context_name=context_name, rnaseq_matrix_filepath=input_rnaseq_filepath, metadata_df=metadata_df, - gene_info_df=pd.read_csv(input_gene_info_filepath), + gene_info_df=await _read_file(input_gene_info_filepath), prep=prep, taxon=taxon_id, replicate_ratio=replicate_ratio, @@ -947,6 +947,9 @@ async def rnaseq_gen( high_batch_ratio=high_batch_ratio, technique=technique, cut_off=cutoff, + force_zfpkm_plot=force_zfpkm_plot, output_boolean_activity_filepath=output_boolean_activity_filepath, output_zscore_normalization_filepath=output_zscore_normalization_filepath, + peak_parameters=PeakIdentificationParameters(height=zfpkm_peak_height, distance=zfpkm_peak_distance), + bandwidth=zfpkm_bandwidth, ) From bdc0f05d63674dc67209b04b1256d507102d93ef Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:58:08 -0600 Subject: [PATCH 098/265] refactor: import required modules --- main/como/proteomics_gen.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/main/como/proteomics_gen.py b/main/como/proteomics_gen.py index d020d71d..ecf568bf 100644 --- a/main/como/proteomics_gen.py +++ b/main/como/proteomics_gen.py @@ -1,5 +1,7 @@ from __future__ import annotations +import sys +from io import TextIOWrapper from pathlib import Path import numpy as np @@ -7,9 +9,10 @@ from fast_bioservices.biodbnet import BioDBNet, Input, Output from loguru import logger -from como import return_placeholder_data +from como.data_types import LOG_FORMAT, LogLevel from como.project import Config from como.proteomics_preprocessing import protein_transform_main +from como.utils import _log_and_raise_error, _set_up_logging, return_placeholder_data # Load Proteomics From 475b27a2c1ecc69bbcd402cd82f221ec4f21f76c Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:58:21 -0600 Subject: [PATCH 099/265] fix: proper calling of _log_and_raise_error --- main/como/proteomics_gen.py | 40 ++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/main/como/proteomics_gen.py b/main/como/proteomics_gen.py index ecf568bf..b3ffe352 100644 --- a/main/como/proteomics_gen.py +++ b/main/como/proteomics_gen.py @@ -21,7 +21,11 @@ def process_proteomics_data(path: Path) -> pd.DataFrame: # Preprocess data, drop na, duplicate ';' in symbol, matrix: pd.DataFrame = pd.read_csv(path) if "gene_symbol" not in matrix.columns: - raise ValueError("No gene_symbol column found in proteomics data.") + _log_and_raise_error( + "No gene_symbol column found in proteomics data.", + error=ValueError, + level=LogLevel.ERROR, + ) matrix["gene_symbol"] = matrix["gene_symbol"].astype(str) matrix.dropna(subset=["gene_symbol"], inplace=True) @@ -130,7 +134,9 @@ def load_empty_dict(): inquiry_full_path = config.data_dir / "config_sheets" / filename if not inquiry_full_path.exists(): - raise FileNotFoundError(f"Error: file not found {inquiry_full_path}") + _log_and_raise_error( + f"Error: file not found {inquiry_full_path}", error=FileNotFoundError, level=LogLevel.ERROR + ) filename = f"Proteomics_{context_name}.csv" full_save_filepath = config.result_dir / context_name / "proteomics" / filename @@ -164,17 +170,37 @@ async def proteomics_gen( ): """Generate proteomics data.""" if not config_filepath.exists(): - raise FileNotFoundError(f"Config file not found at {config_filepath}") + _log_and_raise_error( + f"Config file not found at {config_filepath}", + error=FileNotFoundError, + level=LogLevel.ERROR, + ) if config_filepath.suffix not in (".xlsx", ".xls"): - raise FileNotFoundError(f"Config file must be an xlsx or xls file at {config_filepath}") + _log_and_raise_error( + f"Config file must be an xlsx or xls file at {config_filepath}", + error=FileNotFoundError, + level=LogLevel.ERROR, + ) if not matrix_filepath.exists(): - raise FileNotFoundError(f"Matrix file not found at {matrix_filepath}") + _log_and_raise_error( + f"Matrix file not found at {matrix_filepath}", + error=FileNotFoundError, + level=LogLevel.ERROR, + ) if matrix_filepath.suffix not in {".csv"}: - raise FileNotFoundError(f"Matrix file must be a csv file at {matrix_filepath}") + _log_and_raise_error( + f"Matrix file must be a csv file at {matrix_filepath}", + error=FileNotFoundError, + level=LogLevel.ERROR, + ) if quantile < 0 or quantile > 100: - raise ValueError("Quantile must be an integer from 0 to 100") + _log_and_raise_error( + "Quantile must be an integer from 0 to 100", + error=ValueError, + level=LogLevel.ERROR, + ) quantile /= 100 config_df = pd.read_excel(config_filepath, sheet_name=context_name) From 2c65b0874e56f16a4ffb37a452ce9636091cf1ee Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:58:46 -0600 Subject: [PATCH 100/265] feat: allow providing log level and location --- main/como/proteomics_gen.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/main/como/proteomics_gen.py b/main/como/proteomics_gen.py index b3ffe352..dd50a75d 100644 --- a/main/como/proteomics_gen.py +++ b/main/como/proteomics_gen.py @@ -167,8 +167,12 @@ async def proteomics_gen( high_confidence_replicate_ratio: float = 0.7, high_confidence_batch_ratio: float = 0.7, quantile: int = 25, + log_level: LogLevel = LogLevel.INFO, + log_location: str | TextIOWrapper = sys.stderr, ): """Generate proteomics data.""" + _set_up_logging(level=log_level, location=log_location) + if not config_filepath.exists(): _log_and_raise_error( f"Config file not found at {config_filepath}", From e9d919373ebffe2ba85dee1372964b0af9ccff99 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:59:04 -0600 Subject: [PATCH 101/265] refactor: import required modules --- main/como/merge_xomics.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index f58a69b3..911c0d80 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -1,6 +1,8 @@ from __future__ import annotations -from enum import Enum +import asyncio +import sys +from io import TextIOWrapper from pathlib import Path import numpy as np @@ -8,17 +10,22 @@ from fast_bioservices.biothings.mygene import MyGene from loguru import logger -from como import return_placeholder_data from como.combine_distributions import ( + _begin_combining_distributions, +) +from como.data_types import ( + AdjustmentMethod, + LogLevel, + RNAType, + SourceTypes, _BatchEntry, _BatchNames, - _combine_zscores, _InputMatrices, _OutputCombinedSourceFilepath, _SourceWeights, ) -from como.data_types import RNAPrepMethod from como.project import Config +from como.utils import _log_and_raise_error, _read_file, _set_up_logging, get_missing_gene_data, return_placeholder_data class _MergedHeaderNames: From 632bfa8f3d9d37a3f0419e4160679cd09129a643 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 14:59:40 -0600 Subject: [PATCH 102/265] refactor: remove data-specific Enums These Enums are now found in data_types.py --- main/como/merge_xomics.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index 911c0d80..15c3d350 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -49,21 +49,6 @@ class _HighExpressionHeaderNames: PROTEOMICS = f"{_MergedHeaderNames.PROTEOMICS}_high" -class AdjustmentMethod(Enum): - """Adjustment method for expression requirement based on differences in number of provided data source types.""" - - PROGRESSIVE = "progressive" - REGRESSIVE = "regressive" - FLAT = "flat" - CUSTOM = "custom" - - @classmethod - def from_string(cls, value: str) -> AdjustmentMethod: - """Convert a string to an AdjustmentMethod enum.""" - if value.lower() not in [t.value for t in cls]: - raise ValueError(f"Adjustment method must be one of {cls}; got: {value}") - return cls(value) - def _load_rnaseq_tests(filename, context_name, prep_method: RNAPrepMethod) -> tuple[str, pd.DataFrame]: """Load rnaseq results.""" From f9669a64fd802713a35b64a1aabf741bbde6c444 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:00:03 -0600 Subject: [PATCH 103/265] refactor: async data loading --- main/como/merge_xomics.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index 15c3d350..0bef6ac7 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -49,9 +49,10 @@ class _HighExpressionHeaderNames: PROTEOMICS = f"{_MergedHeaderNames.PROTEOMICS}_high" - -def _load_rnaseq_tests(filename, context_name, prep_method: RNAPrepMethod) -> tuple[str, pd.DataFrame]: +# TODO: If function is no longer needed, remove? +async def _load_rnaseq_tests(filename, context_name, prep_method: RNAType) -> tuple[str, pd.DataFrame]: """Load rnaseq results.""" + logger.debug(f"Loading data for context '{context_name}' using preparation method '{prep_method.value}'") config = Config() def load_dummy_dict(): @@ -62,8 +63,12 @@ def load_dummy_dict(): return load_dummy_dict() inquiry_full_path = config.data_dir / "config_sheets" / filename - if not inquiry_full_path.exists(): # check that config file exist (isn't needed to load, but helps user) - raise FileNotFoundError(f"Error: Config file not found at {inquiry_full_path}") + if not inquiry_full_path.exists(): + _log_and_raise_error( + f"Config file not found at {inquiry_full_path}", + error=FileNotFoundError, + level=LogLevel.ERROR, + ) match prep_method: case RNAPrepMethod.TOTAL: From 938f6cb5fa7aebac4cdc777422affd43009e15fb Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:01:01 -0600 Subject: [PATCH 104/265] refactor: use new RNAType; _log_and_raise_error --- main/como/merge_xomics.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index 0bef6ac7..b176696b 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -71,21 +71,24 @@ def load_dummy_dict(): ) match prep_method: - case RNAPrepMethod.TOTAL: - filename = f"rnaseq_total_{context_name}.csv" - case RNAPrepMethod.MRNA: - filename = f"rnaseq_mrna_{context_name}.csv" - case RNAPrepMethod.SCRNA: - filename = f"rnaseq_scrna_{context_name}.csv" + case RNAType.TRNA: + filename = f"{RNAType.TRNA.value}_{context_name}.csv" + case RNAType.MRNA: + filename = f"{RNAType.MRNA.value}_{context_name}.csv" + case RNAType.SCRNA: + filename = f"{RNAType.SCRNA.value}_{context_name}.csv" case _: - raise ValueError( - f"Unsupported RNA-seq library type: {prep_method.value}. " - f"Must be an option defined in 'RNASeqPreparationMethod'." + _log_and_raise_error( + f"Unsupported RNA-seq library type: {prep_method.value}. Must be one of {', '.join(RNAType)}.", + error=ValueError, + level=LogLevel.ERROR, ) save_filepath = config.result_dir / context_name / prep_method.value / filename if save_filepath.exists(): + logger.debug(f"Loading RNA-seq data from: {save_filepath}") data = pd.read_csv(save_filepath, index_col="entrez_gene_id") + logger.success(f"Successfully loaded RNA-seq data from: {save_filepath}") return context_name, data else: From ed2044ed3d10e1dd9878c0bd4dcf7b3accb742fe Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:01:12 -0600 Subject: [PATCH 105/265] refactor: drop na values --- main/como/merge_xomics.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index b176696b..57d7f7ce 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -107,8 +107,7 @@ def _merge_logical_table(df: pd.DataFrame): :return: pandas dataframe of merged table """ # step 1: get all plural ENTREZ_GENE_IDs in the input table, extract unique IDs - - df.dropna(axis=0, subset=["entrez_gene_id"], inplace=True) + df.dropna(subset=["entrez_gene_id"], inplace=True) df["entrez_gene_id"] = df["entrez_gene_id"].astype(str).str.replace(" /// ", "//").astype(str) id_list: list[str] = df.loc[ From 6074d6b25b6626a7e2aa5397d53f053ba8353e5e Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:02:02 -0600 Subject: [PATCH 106/265] feat: add logging --- main/como/merge_xomics.py | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index 57d7f7ce..75b05be2 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -120,6 +120,7 @@ def _merge_logical_table(df: pd.DataFrame): for i in multiple_entrez_ids: ids = i.split("//") id_list.extend(ids) + logger.trace(f"Processing multiple IDs {ids} for {i}") duplicate_rows = pd.DataFrame([]) for j in ids: @@ -129,15 +130,19 @@ def _merge_logical_table(df: pd.DataFrame): df = pd.concat([df, pd.DataFrame(duplicate_rows)], axis=0, ignore_index=True) df.drop(df[df["entrez_gene_id"] == i].index, inplace=True) + logger.trace(f"Shape after merging duplciated rows: {df.shape}") full_entrez_id_sets: set[str] = set() entrez_dups_list: list[list[str]] = [] multi_entrez_index = list(range(len(multiple_entrez_ids))) + logger.trace("Starting to merge multiple entrez IDs") for i in range(len(multiple_entrez_ids)): if i not in multi_entrez_index: continue + logger.trace(f"Iterating through multi-entrez ids, index {i}") + set1 = set(multiple_entrez_ids[i].split("//")) multi_entrez_index.remove(i) @@ -153,14 +158,17 @@ def _merge_logical_table(df: pd.DataFrame): new_entrez_id = " /// ".join(sortlist) full_entrez_id_sets.add(new_entrez_id) + logger.debug(f"Finished merging multiple entrez IDs, found {len(full_entrez_id_sets)} sets") entrez_dups_list.extend(i.split(" /// ") for i in full_entrez_id_sets) entrez_dups_dict = dict(zip(full_entrez_id_sets, entrez_dups_list)) + logger.trace("Replacing IDs in dataframe") for merged_entrez_id, entrez_dups_list in entrez_dups_dict.items(): df["entrez_gene_id"].replace(to_replace=entrez_dups_list, value=merged_entrez_id, inplace=True) df = df.fillna(-1).groupby(level=0).max() df.replace(-1, np.nan, inplace=True) + logger.trace(f"Shape after merging: {df.shape}") # TODO: Test if this is working properly """ @@ -192,8 +200,10 @@ async def _get_transcriptmoic_details(merged_df: pd.DataFrame, taxon_id: int) -> """ # If _ExpressedHeaderNames.PROTEOMICS.value is in the dataframe, lower the required expression by 1 # We are only trying to get details for transcriptomic data + logger.debug("Obtaining transcriptomic details") transcriptomic_df: pd.DataFrame = merged_df.copy() if _ExpressedHeaderNames.PROTEOMICS in merged_df.columns: + logger.trace("Proteomic data found, modifying required and total expression values") # Get the number of sources required for a gene to be marked "expressed" required_expression = merged_df["required"].iloc[0] @@ -212,6 +222,7 @@ async def _get_transcriptmoic_details(merged_df: pd.DataFrame, taxon_id: int) -> ], inplace=False, ) + logger.trace(f"Modified transcriptomic dataframe: {transcriptomic_df.shape}") # Must recalculate TotalExpressed because proteomic data was removed # If the TotalExpressed column is less than the Required column, set active to 1, otherwise set it to 0 @@ -226,6 +237,7 @@ async def _get_transcriptmoic_details(merged_df: pd.DataFrame, taxon_id: int) -> columns=["entrez_gene_id", "gene_symbol", "description", "gene_type"], index=list(range(len(transcriptomic_df))), ) + logger.trace(f"Querying MyGene for details on {len(transcriptomic_df)} genes") for i, detail in enumerate( await my_gene.query( items=transcriptomic_df["entrez_gene_id"].tolist(), @@ -237,6 +249,8 @@ async def _get_transcriptmoic_details(merged_df: pd.DataFrame, taxon_id: int) -> gene_details.at[i, "gene_symbol"] = detail["symbol"] gene_details.at[i, "description"] = detail["name"] gene_details.at[i, "gene_type"] = detail["type_of_gene"] + + logger.debug("Finished obtaining transcriptomic details") return gene_details @@ -254,6 +268,7 @@ async def _merge_xomics( force_activate_high_confidence: bool = True, adjust_for_missing_sources: bool = False, ): + logger.debug(f"Starting to merge data sources for context '{context_name}'") expression_list: list[str] = [] high_confidence_list: list[str] = [] merge_data = pd.DataFrame() @@ -265,6 +280,7 @@ async def _merge_xomics( (proteomic_boolean_matrix, _ExpressedHeaderNames.PROTEOMICS, _HighExpressionHeaderNames.PROTEOMICS), ): if matrix is None: + logger.trace(f"Skipping {expressed_sourcetype} because it's matrix does not exist") continue matrix: pd.DataFrame # re-define type to assist in type hinting for IDEs @@ -273,18 +289,22 @@ async def _merge_xomics( matrix.rename(columns={"expressed": expressed_sourcetype, "high": high_expressed_sourcetype}, inplace=True) merge_data = matrix if merge_data.empty else merge_data.merge(matrix, on="entrez_gene_id", how="outer") + logger.trace(f"Shape of merged data before merging logical tables: {merge_data.shape}") if merge_data.empty: - logger.critical( + logger.warning( f"No data is available for the '{context_name}' context. If this is intentional, ignore this error." ) return {} merge_data = _merge_logical_table(merge_data) + logger.debug(f"Shape of merged data after merging logical table: {merge_data.shape}") num_sources = len(expression_list) merge_data["active"] = 0 merge_data["required"] = 0 + logger.trace(f"Number of data sources: {num_sources}") if adjust_for_missing_sources: # Subtract 1 from requirement per missing source + logger.trace("Adjusting for missing data sources") merge_data.loc[:, "required"] = merge_data[expression_list].apply( lambda x: expression_requirement - (num_sources - x.count()) if (expression_requirement - (num_sources - x.count()) > 0) @@ -292,22 +312,30 @@ async def _merge_xomics( axis=1, ) else: # Do not adjust for missing sources + logger.trace("Not adjusting for missing data sources") merge_data.loc[:, "required"] = merge_data[expression_list].apply( lambda x: expression_requirement if (expression_requirement - (num_sources - x.count()) > 0) else 1, axis=1 ) + logger.trace("Created expression requirement column") # Count the number of sources each gene is active in # set to active in final output if we meet the adjusted expression requirement merge_data["total_expressed"] = merge_data[expression_list].sum(axis=1) merge_data.loc[merge_data["total_expressed"] >= merge_data["required"], "active"] = 1 + logger.trace("Created total expression requirement column") if force_activate_high_confidence: # If a gene is high-confidence in at least 1 data source, set it to active + logger.trace("Forcing high confidence genes") merge_data.loc[merge_data[high_confidence_list].sum(axis=1) > 0, "active"] = 1 merge_data.to_csv(output_merged_filepath, index=False) + logger.success(f"Saved merged data to {output_merged_filepath}") + + logger.debug(f"Generating transcriptomic details using {output_merged_filepath}") transcriptomic_details = await _get_transcriptmoic_details(merge_data, taxon_id=taxon_id) + logger.debug(f"Saving transcriptomic details to {output_transcriptomic_details_filepath}") transcriptomic_details.to_csv(output_transcriptomic_details_filepath, index=False) - + logger.success(f"Saved transcriptomic details to {output_transcriptomic_details_filepath}") return {context_name: output_gene_activity_filepath.as_posix()} @@ -383,6 +411,7 @@ async def _process( weighted_z_floor=weighted_z_floor, weighted_z_ceiling=weighted_z_ceiling, ) + logger.trace("Finished merging Z-Scores") # the more data sources available, the higher the expression requirement for the gene if adjust_method == AdjustmentMethod.PROGRESSIVE: @@ -394,6 +423,7 @@ async def _process( adjusted_expression_requirement = expression_requirement - (4 - num_sources) elif adjust_method == AdjustmentMethod.FLAT: adjusted_expression_requirement = expression_requirement + logger.debug(f"Adjusted expression requirement: {adjusted_expression_requirement}") if adjusted_expression_requirement != expression_requirement: logger.debug( From 9b520491185b70d2362f338d80a696795ee8fd7b Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:02:57 -0600 Subject: [PATCH 107/265] refactor: type hinting; drop na values --- main/como/merge_xomics.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index 75b05be2..745cdca9 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -271,7 +271,7 @@ async def _merge_xomics( logger.debug(f"Starting to merge data sources for context '{context_name}'") expression_list: list[str] = [] high_confidence_list: list[str] = [] - merge_data = pd.DataFrame() + merge_data: pd.DataFrame = pd.DataFrame() for matrix, expressed_sourcetype, high_expressed_sourcetype in ( (trna_boolean_matrix, _ExpressedHeaderNames.TRNASEQ, _HighExpressionHeaderNames.TRNASEQ), @@ -328,12 +328,14 @@ async def _merge_xomics( logger.trace("Forcing high confidence genes") merge_data.loc[merge_data[high_confidence_list].sum(axis=1) > 0, "active"] = 1 + merge_data.dropna(inplace=True) merge_data.to_csv(output_merged_filepath, index=False) logger.success(f"Saved merged data to {output_merged_filepath}") logger.debug(f"Generating transcriptomic details using {output_merged_filepath}") transcriptomic_details = await _get_transcriptmoic_details(merge_data, taxon_id=taxon_id) logger.debug(f"Saving transcriptomic details to {output_transcriptomic_details_filepath}") + transcriptomic_details.dropna(inplace=True) transcriptomic_details.to_csv(output_transcriptomic_details_filepath, index=False) logger.success(f"Saved transcriptomic details to {output_transcriptomic_details_filepath}") return {context_name: output_gene_activity_filepath.as_posix()} From 38a9f1e74e3e02ecd6d1b7e15f2ffd08107dae49 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:03:16 -0600 Subject: [PATCH 108/265] feat: added function to update missing genome data --- main/como/merge_xomics.py | 45 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index 745cdca9..b3f5025b 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -341,6 +341,51 @@ async def _merge_xomics( return {context_name: output_gene_activity_filepath.as_posix()} +async def _update_missing_data(input_matrices: _InputMatrices, taxon_id: int) -> _InputMatrices: + logger.trace("Updating missing genomic data") + matrix_keys: dict[str, list[pd.DataFrame]] = { + "trna": [input_matrices.trna], + "mrna": [input_matrices.mrna], + "scrna": [input_matrices.scrna], + "proteomics": [input_matrices.proteomics], + } + logger.trace(f"Gathering missing data for data sources: {','.join(key for key in matrix_keys if key is not None)}") + # fmt: off + results = await asyncio.gather( + *[ + # Using 'is not None' is required because the truth value of a Dataframe is ambiguous + get_missing_gene_data(values=input_matrices.trna, taxon_id=taxon_id) if input_matrices.trna is not None else asyncio.sleep(0), # noqa: E501 + get_missing_gene_data(values=input_matrices.mrna, taxon_id=taxon_id) if input_matrices.mrna is not None else asyncio.sleep(0), # noqa: E501 + get_missing_gene_data(values=input_matrices.scrna, taxon_id=taxon_id) if input_matrices.scrna is not None else asyncio.sleep(0), # noqa: E501 + get_missing_gene_data(values=input_matrices.proteomics, taxon_id=taxon_id) if input_matrices.proteomics is not None else asyncio.sleep(0), # noqa: E501 + ] + ) + # fmt: on + for i, key in enumerate(matrix_keys): + matrix_keys[key].append(results[i]) + + for matrix_name, (matrix, conversion) in matrix_keys.items(): + matrix: pd.DataFrame + if matrix is not None: + # fmt: off + existing_data = ( + "gene_symbol" if "gene_symbol" in matrix + else "entrez_gene_id" if "entrez_gene_id" in matrix + else "ensembl_gene_id" + ) + # fmt: on + logger.trace(f"Merging conversion data for {matrix_name}, existing id column is: {existing_data}") + input_matrices[matrix_name] = ( + input_matrices[matrix_name] + .merge(conversion, how="left", on=[existing_data]) + .dropna() + .reset_index(drop=True) + ) + + logger.debug("Updated missing genomic data") + return input_matrices + + async def _process( *, context_name: str, From 11cd6b426fef4063da836ccd73437f42244882f7 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:04:53 -0600 Subject: [PATCH 109/265] refactor: build and use new parameter data types --- main/como/merge_xomics.py | 145 ++++++++++++++++++-------------------- 1 file changed, 70 insertions(+), 75 deletions(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index b3f5025b..b5483afe 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -389,22 +389,10 @@ async def _update_missing_data(input_matrices: _InputMatrices, taxon_id: int) -> async def _process( *, context_name: str, - trna_matrix: pd.DataFrame | None, - mrna_matrix: pd.DataFrame | None, - scrna_matrix: pd.DataFrame | None, - proteomic_matrix: pd.DataFrame | None, - trna_boolean_matrix: pd.DataFrame | None, - mrna_boolean_matrix: pd.DataFrame | None, - scrna_boolean_matrix: pd.DataFrame | None, - proteomic_boolean_matrix: pd.DataFrame | None, - trna_batches: dict[int, list[str]], - mrna_batches: dict[int, list[str]], - scrna_batches: dict[int, list[str]], - proteomic_batches: dict[int, list[str]], - trna_weight: int, - mrna_weight: int, - scrna_weight: int, - proteomic_weight: int, + input_matrices: _InputMatrices, + boolean_matrices: _InputMatrices, + batch_names: _BatchNames, + source_weights: _SourceWeights, taxon_id: int, minimum_source_expression: int, expression_requirement: int, @@ -416,10 +404,7 @@ async def _process( adjust_for_missing_sources: bool, output_merge_activity_filepath: Path, output_transcriptomic_details_filepath: Path, - output_trna_activity_filepath: Path | None, - output_mrna_activity_filepath: Path | None, - output_scrna_activity_filepath: Path | None, - output_proteomic_activity_filepath: Path | None, + output_activity_filepaths: _OutputCombinedSourceFilepath, output_final_model_scores_filepath: Path, output_figure_dirpath: Path | None, ): @@ -592,68 +577,81 @@ async def merge_xomics( # noqa: C901 if output_figure_dirpath: output_figure_dirpath.mkdir(parents=True, exist_ok=True) - # fmt: off - trna_matrix: pd.DataFrame | None = ( - pd.read_csv(trna_matrix_or_filepath) if isinstance(trna_matrix_or_filepath, Path) - else trna_matrix_or_filepath if isinstance(trna_matrix_or_filepath, pd.DataFrame) - else None - ) - mrna_matrix: pd.DataFrame | None = ( - pd.read_csv(mrna_matrix_or_filepath) if isinstance(mrna_matrix_or_filepath, Path) - else mrna_matrix_or_filepath if isinstance(mrna_matrix_or_filepath, pd.DataFrame) - else None + # Build trna items + trna_matrix: pd.DataFrame | None + trna_boolean_matrix: pd.DataFrame | None + trna_metadata: pd.DataFrame | None + trna_matrix, trna_boolean_matrix, trna_metadata = await asyncio.gather( + *[ + _read_file(trna_matrix_or_filepath), + _read_file(trna_boolean_matrix_or_filepath), + _read_file(trna_metadata_filepath_or_df), + ] ) - scrna_matrix: pd.DataFrame | None = ( - pd.read_csv(scrna_matrix_or_filepath) if isinstance(scrna_matrix_or_filepath, Path) - else scrna_matrix_or_filepath if isinstance(scrna_matrix_or_filepath, pd.DataFrame) - else None + + # Build mrna items + mrna_matrix: pd.DataFrame | None + mrna_boolean_matrix: pd.DataFrame | None + mrna_metadata: pd.DataFrame | None + mrna_matrix, mrna_boolean_matrix, mrna_metadata = await asyncio.gather( + *[ + _read_file(mrna_matrix_or_filepath), + _read_file(mrna_boolean_matrix_or_filepath), + _read_file(mrna_metadata_filepath_or_df), + ] ) - proteomic_matrix: pd.DataFrame | None = ( - pd.read_csv(proteomic_matrix_or_filepath) if isinstance(proteomic_matrix_or_filepath, Path) - else proteomic_matrix_or_filepath if isinstance(proteomic_matrix_or_filepath, pd.DataFrame) - else None + + # build scrna items + scrna_matrix: pd.DataFrame | None + scrna_boolean_matrix: pd.DataFrame | None + scrna_metadata: pd.DataFrame | None + scrna_matrix, scrna_boolean_matrix, scrna_metadata = await asyncio.gather( + *[ + _read_file(scrna_matrix_or_filepath), + _read_file(scrna_boolean_matrix_or_filepath), + _read_file(scrna_metadata_filepath_or_df), + ] ) - trna_boolean_matrix: pd.DataFrame | None = ( - pd.read_csv(trna_boolean_matrix_or_filepath) if isinstance(trna_boolean_matrix_or_filepath, Path) - else trna_boolean_matrix_or_filepath if isinstance(trna_boolean_matrix_or_filepath, pd.DataFrame) - else None + # build proteomic items + proteomic_matrix: pd.DataFrame | None + proteomic_boolean_matrix: pd.DataFrame | None + proteomic_metadata: pd.DataFrame | None + proteomic_matrix, proteomic_boolean_matrix, proteomic_metadata = await asyncio.gather( + *[ + _read_file(proteomic_matrix_or_filepath), + _read_file(proteomic_boolean_matrix_or_filepath), + _read_file(proteomic_metadata_filepath_or_df), + ] ) - mrna_boolean_matrix: pd.DataFrame | None = ( - pd.read_csv(mrna_boolean_matrix_or_filepath) if isinstance(mrna_boolean_matrix_or_filepath, Path) - else mrna_boolean_matrix_or_filepath if isinstance(mrna_boolean_matrix_or_filepath, pd.DataFrame) - else None + + source_weights = _SourceWeights(trna=trna_weight, mrna=mrna_weight, scrna=scrna_weight, proteomics=proteomic_weight) + input_matrices = _InputMatrices(trna=trna_matrix, mrna=mrna_matrix, scrna=scrna_matrix, proteomics=proteomic_matrix) + boolean_matrices = _InputMatrices( + trna=trna_boolean_matrix, + mrna=mrna_boolean_matrix, + scrna=scrna_boolean_matrix, + proteomics=proteomic_boolean_matrix, ) - scrna_boolean_matrix: pd.DataFrame | None = ( - pd.read_csv(scrna_boolean_matrix_or_filepath) if isinstance(scrna_boolean_matrix_or_filepath, Path) - else scrna_boolean_matrix_or_filepath if isinstance(scrna_boolean_matrix_or_filepath, pd.DataFrame) - else None + output_activity_filepaths = _OutputCombinedSourceFilepath( + trna=output_trna_activity_filepath, + mrna=output_mrna_activity_filepath, + scrna=output_scrna_activity_filepath, + proteomics=output_proteomic_activity_filepath, ) - proteomic_boolean_matrix: pd.DataFrame | None = ( - pd.read_csv(proteomic_boolean_matrix_or_filepath) if isinstance(proteomic_boolean_matrix_or_filepath, Path) - else proteomic_boolean_matrix_or_filepath if isinstance(proteomic_boolean_matrix_or_filepath, pd.DataFrame) - else None + batch_names = _build_batches( + trna_metadata=trna_metadata, + mrna_metadata=mrna_metadata, + scrna_metadata=scrna_metadata, + proteomic_metadata=proteomic_metadata, ) - # fmt: on await _process( context_name=context_name, - trna_matrix=trna_matrix, - mrna_matrix=mrna_matrix, - scrna_matrix=scrna_matrix, - proteomic_matrix=proteomic_matrix, - trna_boolean_matrix=trna_boolean_matrix, - mrna_boolean_matrix=mrna_boolean_matrix, - scrna_boolean_matrix=scrna_boolean_matrix, - proteomic_boolean_matrix=proteomic_boolean_matrix, - trna_batches=trna_batches, - mrna_batches=mrna_batches, - scrna_batches=scrna_batches, - proteomic_batches=proteomic_batches, - trna_weight=trna_weight, - mrna_weight=mrna_weight, - scrna_weight=scrna_weight, - proteomic_weight=proteomic_weight, + input_matrices=input_matrices, + boolean_matrices=boolean_matrices, + source_weights=source_weights, + batch_names=batch_names, taxon_id=taxon_id, minimum_source_expression=minimum_source_expression, expression_requirement=expression_requirement, @@ -663,12 +661,9 @@ async def merge_xomics( # noqa: C901 merge_zfpkm_distribution=merge_zfpkm_distribution, force_activate_high_confidence=force_activate_high_confidence, adjust_for_missing_sources=adjust_for_na, + output_activity_filepaths=output_activity_filepaths, output_merge_activity_filepath=output_merge_activity_filepath, output_transcriptomic_details_filepath=output_transcriptomic_details_filepath, - output_trna_activity_filepath=output_trna_activity_filepath, - output_mrna_activity_filepath=output_mrna_activity_filepath, - output_scrna_activity_filepath=output_scrna_activity_filepath, - output_proteomic_activity_filepath=output_proteomic_activity_filepath, output_final_model_scores_filepath=output_final_model_scores_filepath, output_figure_dirpath=output_figure_dirpath, ) From 0d484a2d53644f113f05bf619ff98f45037063e5 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:05:38 -0600 Subject: [PATCH 110/265] refactor: pass new parameter data types --- main/como/merge_xomics.py | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index b5483afe..d2ff4045 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -410,34 +410,21 @@ async def _process( ): """Merge different data sources for each context type.""" num_sources = sum(1 for source in [trna_matrix, mrna_matrix, scrna_matrix, proteomic_matrix] if source is not None) + logger.trace( + f"Settings: Min Expression: {minimum_source_expression}, Expression Requirement: {expression_requirement}, " + f"Weighted Z-Score Floor: {weighted_z_floor}, Weighted Z-Score Ceiling: {weighted_z_ceiling}, " + f"Adjust Method: {adjust_method.value}, Merge Z-Scores: {merge_zfpkm_distribution}, " + f"Force High Confidence: {force_activate_high_confidence}, Adjust for Missing: {adjust_for_missing_sources}" + ) if merge_zfpkm_distribution: - _combine_zscores( + logger.trace("Merging Z-Scores") + await _begin_combining_distributions( context_name=context_name, - input_matrices=_InputMatrices( - trna=trna_matrix, - mrna=mrna_matrix, - scrna=scrna_matrix, - proteomics=proteomic_matrix, - ), - batch_names=_BatchNames( - trna=[_BatchEntry(batch_num=n, sample_names=s) for n, s in trna_batches.items()], - mrna=[_BatchEntry(batch_num=n, sample_names=s) for n, s in mrna_batches.items()], - scrna=[_BatchEntry(batch_num=n, sample_names=s) for n, s in scrna_batches.items()], - proteomics=[_BatchEntry(batch_num=n, sample_names=s) for n, s in proteomic_batches.items()], - ), - source_weights=_SourceWeights( - trna=trna_weight, - mrna=mrna_weight, - scrna=scrna_weight, - proteomics=proteomic_weight, - ), - output_filepaths=_OutputCombinedSourceFilepath( - trna=output_trna_activity_filepath, - mrna=output_mrna_activity_filepath, - scrna=output_scrna_activity_filepath, - proteomics=output_proteomic_activity_filepath, - ), + input_matrices=input_matrices, + batch_names=batch_names, + source_weights=source_weights, + output_filepaths=output_activity_filepaths, output_figure_dirpath=output_figure_dirpath, output_final_model_scores=output_final_model_scores_filepath, weighted_z_floor=weighted_z_floor, From 07fc452c04061d0a6f4ab56b169de7998a4bea60 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:06:05 -0600 Subject: [PATCH 111/265] refactor: calculate variables near their usage --- main/como/merge_xomics.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index d2ff4045..5af5e63c 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -409,7 +409,6 @@ async def _process( output_figure_dirpath: Path | None, ): """Merge different data sources for each context type.""" - num_sources = sum(1 for source in [trna_matrix, mrna_matrix, scrna_matrix, proteomic_matrix] if source is not None) logger.trace( f"Settings: Min Expression: {minimum_source_expression}, Expression Requirement: {expression_requirement}, " f"Weighted Z-Score Floor: {weighted_z_floor}, Weighted Z-Score Ceiling: {weighted_z_ceiling}, " @@ -417,6 +416,10 @@ async def _process( f"Force High Confidence: {force_activate_high_confidence}, Adjust for Missing: {adjust_for_missing_sources}" ) + # Collect missing genomic data for each of the input items in asynchronous parallel + input_matrices = await _update_missing_data(input_matrices, taxon_id) + logger.trace("Missing data updated") + if merge_zfpkm_distribution: logger.trace("Merging Z-Scores") await _begin_combining_distributions( @@ -433,6 +436,7 @@ async def _process( logger.trace("Finished merging Z-Scores") # the more data sources available, the higher the expression requirement for the gene + num_sources = sum(1 for source in input_matrices if source is not None) if adjust_method == AdjustmentMethod.PROGRESSIVE: adjusted_expression_requirement = (num_sources - minimum_source_expression) + expression_requirement # the more data sources available, the lower the expression requirement for the gene From c371c124f49870e4421c3dc862639a836b97a118 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:06:24 -0600 Subject: [PATCH 112/265] style: more verbose variable name --- main/como/merge_xomics.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index 5af5e63c..b13d6a7b 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -471,13 +471,14 @@ async def _process( ) adjusted_expression_requirement = 1 + logger.debug(f"Final Expression Requirement: {adjusted_expression_requirement}") await _merge_xomics( context_name=context_name, expression_requirement=adjusted_expression_requirement, - trna_boolean_matrix=trna_boolean_matrix, - mrna_boolean_matrix=mrna_boolean_matrix, - scrna_boolean_matrix=scrna_boolean_matrix, - proteomic_boolean_matrix=proteomic_boolean_matrix, + trna_boolean_matrix=boolean_matrices.trna, + mrna_boolean_matrix=boolean_matrices.mrna, + scrna_boolean_matrix=boolean_matrices.scrna, + proteomic_boolean_matrix=boolean_matrices.proteomics, output_merged_filepath=output_merge_activity_filepath, output_gene_activity_filepath=output_final_model_scores_filepath, output_transcriptomic_details_filepath=output_transcriptomic_details_filepath, From 026f1cc3204a0526c1f6d7f9310341536ace53ff Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:06:39 -0600 Subject: [PATCH 113/265] feat: add functions for building batch data --- main/como/merge_xomics.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index b13d6a7b..6c74a1d5 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -488,6 +488,26 @@ async def _process( ) +def _build_batches( + trna_metadata: pd.DataFrame | None, + mrna_metadata: pd.DataFrame | None, + scrna_metadata: pd.DataFrame | None, + proteomic_metadata: pd.DataFrame | None, +) -> _BatchNames: + batch_names = _BatchNames(**{source.name.lower(): [] for source in SourceTypes}) + for source, metadata in zip(SourceTypes, [trna_metadata, mrna_metadata, scrna_metadata, proteomic_metadata]): + source: SourceTypes + metadata: pd.DataFrame + if metadata is None: + logger.trace(f"Metadata for source '{source.value}' is None, skipping") + continue + + metadata: pd.DataFrame # Re-assign type to assist in type hinting + for batch_num, study in enumerate(sorted(metadata["study"].unique()), start=1): + study_sample_names = metadata[metadata["study"] == study]["sample_name"].tolist() + batch_names[source.value].append(_BatchEntry(batch_num=batch_num, sample_names=study_sample_names)) + logger.debug(f"Found {len(study_sample_names)} sample names for study '{study}', batch number {batch_num}") + return batch_names async def merge_xomics( # noqa: C901 context_name: str, trna_matrix_or_filepath: Path | pd.DataFrame | None, From ebf3edd82290af7fc8289f519cb38d4374f39c70 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:06:55 -0600 Subject: [PATCH 114/265] feat: add function for validating data soruces --- main/como/merge_xomics.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index 6c74a1d5..8ba535eb 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -508,6 +508,31 @@ def _build_batches( batch_names[source.value].append(_BatchEntry(batch_num=batch_num, sample_names=study_sample_names)) logger.debug(f"Found {len(study_sample_names)} sample names for study '{study}', batch number {batch_num}") return batch_names + + +def _validate_source_arguments( + source: SourceTypes, + *args, +) -> None: + """Validate arguments for each source are valid. + + If at least one input item is provided, validate that all required items are also present. + + :param matrix_or_filepath: The gene count matrix or filepath + :param boolean_matrix_or_filepath: The boolean matrix of gene activities + :param metadata_filepath_or_df: Dataframe or filepath to sample metadata + :param output_activity_filepath: Output filepath location + :param source: Source type + + """ + if any(i for i in args) and not all(i for i in args): + _log_and_raise_error( + f"Must specify all or none of '{source.value}' arguments", + error=ValueError, + level=LogLevel.ERROR, + ) + + async def merge_xomics( # noqa: C901 context_name: str, trna_matrix_or_filepath: Path | pd.DataFrame | None, From 0f1d584dca49acf0ea45d12dae413c17c561d483 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:07:40 -0600 Subject: [PATCH 115/265] refactor!: provide None as default argument For parameters that are not needed, None is a default argument --- main/como/merge_xomics.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index 8ba535eb..f89d7c27 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -535,27 +535,27 @@ def _validate_source_arguments( async def merge_xomics( # noqa: C901 context_name: str, - trna_matrix_or_filepath: Path | pd.DataFrame | None, - mrna_matrix_or_filepath: Path | pd.DataFrame | None, - scrna_matrix_or_filepath: Path | pd.DataFrame | None, - proteomic_matrix_or_filepath: Path | pd.DataFrame | None, - trna_boolean_matrix_or_filepath: Path | pd.DataFrame | None, - mrna_boolean_matrix_or_filepath: Path | pd.DataFrame | None, - scrna_boolean_matrix_or_filepath: Path | pd.DataFrame | None, - proteomic_boolean_matrix_or_filepath: Path | pd.DataFrame | None, - trna_batches: dict[int, list[str]], - mrna_batches: dict[int, list[str]], - scrna_batches: dict[int, list[str]], - proteomic_batches: dict[int, list[str]], output_merge_activity_filepath: Path, output_transcriptomic_details_filepath: Path, - output_trna_activity_filepath: Path | None, - output_mrna_activity_filepath: Path | None, - output_scrna_activity_filepath: Path | None, - output_proteomic_activity_filepath: Path | None, output_final_model_scores_filepath: Path, output_figure_dirpath: Path | None, taxon_id: int, + trna_matrix_or_filepath: Path | pd.DataFrame | None = None, + mrna_matrix_or_filepath: Path | pd.DataFrame | None = None, + scrna_matrix_or_filepath: Path | pd.DataFrame | None = None, + proteomic_matrix_or_filepath: Path | pd.DataFrame | None = None, + trna_boolean_matrix_or_filepath: Path | pd.DataFrame | None = None, + mrna_boolean_matrix_or_filepath: Path | pd.DataFrame | None = None, + scrna_boolean_matrix_or_filepath: Path | pd.DataFrame | None = None, + proteomic_boolean_matrix_or_filepath: Path | pd.DataFrame | None = None, + trna_metadata_filepath_or_df: Path | pd.DataFrame | None = None, + mrna_metadata_filepath_or_df: Path | pd.DataFrame | None = None, + scrna_metadata_filepath_or_df: Path | pd.DataFrame | None = None, + proteomic_metadata_filepath_or_df: Path | pd.DataFrame | None = None, + output_trna_activity_filepath: Path | None = None, + output_mrna_activity_filepath: Path | None = None, + output_scrna_activity_filepath: Path | None = None, + output_proteomic_activity_filepath: Path | None = None, trna_weight: int = 1, mrna_weight: int = 1, scrna_weight: int = 1, From f0a2aab1c55770f43829378ebc51dd07f18f46ff Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:08:00 -0600 Subject: [PATCH 116/265] refactor: better building of source data variables --- main/como/merge_xomics.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index f89d7c27..61dc5580 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -583,17 +583,26 @@ async def merge_xomics( # noqa: C901 proteomic_matrix_or_filepath, ] ) + source_data = { + SourceTypes.TRNA: (trna_matrix_or_filepath, trna_boolean_matrix_or_filepath, trna_metadata_filepath_or_df, output_trna_activity_filepath), # noqa: E501 + SourceTypes.MRNA: (mrna_matrix_or_filepath, mrna_boolean_matrix_or_filepath, mrna_metadata_filepath_or_df, output_mrna_activity_filepath), # noqa: E501 + SourceTypes.SCRNA: (scrna_matrix_or_filepath, scrna_boolean_matrix_or_filepath, scrna_metadata_filepath_or_df, output_scrna_activity_filepath), # noqa: E501 + SourceTypes.PROTEOMICS: (proteomic_matrix_or_filepath, proteomic_boolean_matrix_or_filepath, proteomic_metadata_filepath_or_df, output_proteomic_activity_filepath), # noqa: E501 + } + # fmt: on + for source in source_data: + _validate_source_arguments(source, source_data[source]) if all( file is None - for file in [ + for file in ( trna_matrix_or_filepath, mrna_matrix_or_filepath, scrna_matrix_or_filepath, proteomic_matrix_or_filepath, - ] + ) ): - raise ValueError("No data was passed!") + _log_and_raise_error("No data was passed!", error=ValueError, level=LogLevel.ERROR) if adjust_method not in AdjustmentMethod: raise ValueError(f"Adjustment method must be one of {AdjustmentMethod}; got: {adjust_method}") From b9bade66cf0c46dee7868d4f673667dc183b1407 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:08:20 -0600 Subject: [PATCH 117/265] feat: allow providing log levela and location --- main/como/merge_xomics.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index 61dc5580..601255b2 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -568,10 +568,14 @@ async def merge_xomics( # noqa: C901 merge_zfpkm_distribution: bool = False, weighted_z_floor: int = -6, weighted_z_ceiling: int = 6, + log_level: LogLevel = LogLevel.INFO, + log_location: str | TextIOWrapper = sys.stderr, ): """Merge expression tables of multiple sources (RNA-seq, proteomics) into one.""" if expression_requirement < 1: raise ValueError("Expression requirement must be at least 1!") + _set_up_logging(level=log_level, location=log_location) + logger.info(f"Starting to merge all omics data for context: '{context_name}'") if expression_requirement is None: expression_requirement = sum( From 325b559a3f388750e592c4a61b3eb5f84c9b9be1 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:08:40 -0600 Subject: [PATCH 118/265] refactor: move variable creation closer to usage --- main/como/merge_xomics.py | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index 601255b2..d507d683 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -572,21 +572,10 @@ async def merge_xomics( # noqa: C901 log_location: str | TextIOWrapper = sys.stderr, ): """Merge expression tables of multiple sources (RNA-seq, proteomics) into one.""" - if expression_requirement < 1: - raise ValueError("Expression requirement must be at least 1!") _set_up_logging(level=log_level, location=log_location) logger.info(f"Starting to merge all omics data for context: '{context_name}'") - if expression_requirement is None: - expression_requirement = sum( - test is not None - for test in [ - trna_matrix_or_filepath, - mrna_matrix_or_filepath, - scrna_matrix_or_filepath, - proteomic_matrix_or_filepath, - ] - ) + # fmt: off source_data = { SourceTypes.TRNA: (trna_matrix_or_filepath, trna_boolean_matrix_or_filepath, trna_metadata_filepath_or_df, output_trna_activity_filepath), # noqa: E501 SourceTypes.MRNA: (mrna_matrix_or_filepath, mrna_boolean_matrix_or_filepath, mrna_metadata_filepath_or_df, output_mrna_activity_filepath), # noqa: E501 From 463d54571d8aed775e63b5aff3b8eb13535edce9 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:09:03 -0600 Subject: [PATCH 119/265] refactor: use _log_and_raise_error --- main/como/merge_xomics.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index d507d683..a25f8e78 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -598,7 +598,29 @@ async def merge_xomics( # noqa: C901 _log_and_raise_error("No data was passed!", error=ValueError, level=LogLevel.ERROR) if adjust_method not in AdjustmentMethod: - raise ValueError(f"Adjustment method must be one of {AdjustmentMethod}; got: {adjust_method}") + _log_and_raise_error( + f"Adjustment method must be one of {AdjustmentMethod}; got: {adjust_method}", + error=ValueError, + level=LogLevel.ERROR, + ) + + if expression_requirement < 1: + logger.warning( + f"Expression requirement must be at least 1! Setting to the minimum of 1 now. Got: {expression_requirement}" + ) + expression_requirement = 1 + + if expression_requirement is None: + expression_requirement = sum( + test is not None + for test in ( + trna_matrix_or_filepath, + mrna_matrix_or_filepath, + scrna_matrix_or_filepath, + proteomic_matrix_or_filepath, + ) + ) + logger.debug(f"Expression requirement not specified; setting to {expression_requirement}") output_final_model_scores_filepath.parent.mkdir(parents=True, exist_ok=True) if output_merge_activity_filepath: From f1c242d54b0bc0f161736718a755b75196c74b75 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:09:18 -0600 Subject: [PATCH 120/265] refactor: import required modules --- main/como/create_context_specific_model.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index f6ac8b91..4fc95c79 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -1,12 +1,10 @@ from __future__ import annotations -import argparse -import ast import collections import re +import sys from collections.abc import Sequence -from dataclasses import dataclass -from enum import Enum +from io import TextIOWrapper from pathlib import Path from typing import NamedTuple @@ -22,9 +20,6 @@ from troppo.methods.reconstruction.imat import IMAT, IMATProperties from troppo.methods.reconstruction.tINIT import tINIT, tINITProperties -from como.project import Config -from como.utils import Algorithm, Compartments, split_gene_expression_data, stringlist_to_list - class Solver(Enum): """Solver used to seed context specific model.""" From 437082a0c91b20f05647528b64454b334d8c68ac Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:09:30 -0600 Subject: [PATCH 121/265] refactor!: move Solver to data_types --- main/como/create_context_specific_model.py | 25 ++-------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 4fc95c79..d0d44391 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -20,29 +20,8 @@ from troppo.methods.reconstruction.imat import IMAT, IMATProperties from troppo.methods.reconstruction.tINIT import tINIT, tINITProperties - -class Solver(Enum): - """Solver used to seed context specific model.""" - - GLPK = "GLPK" - GUROBI = "GUROBI" - SCIPY = "SCIPY" - GLPK_EXACT = "GLPK_EXACT" - - @staticmethod - def from_string(value: str) -> Solver: - """Convert string to Solver enum.""" - match value.lower(): - case "glpk": - return Solver.GLPK - case "gurobi": - return Solver.GUROBI - case "scipy": - return Solver.SCIPY - case "glpk_exact": - return Solver.GLPK_EXACT - case _: - raise ValueError(f"Unknown solver: {value}") +from como.data_types import Algorithm, CobraCompartments, LogLevel, Solver +from como.utils import _log_and_raise_error, _read_file, _set_up_logging, split_gene_expression_data class _BoundaryReactions(NamedTuple): From 4694a5af64e14c397b513e2b8c621a32d6a922af Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:09:47 -0600 Subject: [PATCH 122/265] refactor: remove _Arguments cli parsing --- main/como/create_context_specific_model.py | 48 ---------------------- 1 file changed, 48 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index d0d44391..692b7f68 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -40,54 +40,6 @@ class _BuildResults(NamedTuple): infeasible_reactions: pd.DataFrame -@dataclass -class _Arguments: - """Arguments for creating a context specific model.""" - - context_name: str - reference_model: Path - active_genes_filepath: Path - objective: str - boundary_reactions_filepath: Path - exclude_reactions_filepath: Path - force_reactions_filepath: Path - recon_algorithm: Algorithm - solver: Solver - low_threshold: int - high_threshold: int - output_filetypes: list[str] - - def __post_init__(self): - self.reference_model = Path(self.reference_model) - self.active_genes_filepath = Path(self.active_genes_filepath) - self.boundary_reactions_filepath = ( - Path(self.boundary_reactions_filepath) if self.boundary_reactions_filepath is not None else None - ) - self.exclude_reactions_filepath = ( - Path(self.exclude_reactions_filepath) if self.exclude_reactions_filepath is not None else None - ) - self.force_reactions_filepath = ( - Path(self.force_reactions_filepath) if self.force_reactions_filepath is not None else None - ) - - if not self.reference_model.exists(): - raise FileNotFoundError(f"Reference model not found at {self.reference_model}") - if not self.active_genes_filepath.exists(): - raise FileNotFoundError(f"Active genes file not found at {self.active_genes_filepath}") - if self.boundary_reactions_filepath and not self.boundary_reactions_filepath.exists(): - raise FileNotFoundError(f"Boundary reactions file not found at {self.boundary_reactions_filepath}") - if self.exclude_reactions_filepath and not self.exclude_reactions_filepath.exists(): - raise FileNotFoundError(f"Exclude reactions file not found at {self.exclude_reactions_filepath}") - if self.force_reactions_filepath and not self.force_reactions_filepath.exists(): - raise FileNotFoundError(f"Force reactions file not found at {self.force_reactions_filepath}") - - if self.high_threshold < self.low_threshold: - raise ValueError( - f"Low threshold must be less than high threshold. " - f"Received low threshold: {self.low_threshold}, high threshold: {self.high_threshold}" - ) - - def _correct_bracket(rule: str, name: str) -> str: """Correct GPR rules to format readable by.""" rule_match = re.search(r"or|and", rule) From 91a538fbed6b627bc999f62f49a0b4d01246000e Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:10:18 -0600 Subject: [PATCH 123/265] fix: bracket and logical gene rule creation --- main/como/create_context_specific_model.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 692b7f68..96ca2cae 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -64,9 +64,9 @@ def _correct_bracket(rule: str, name: str) -> str: elif len(left_name) > 0 and char == left_name[0]: new_right_rule.append(char) left_name = left_name[1:] - new_left_rule = "".join(new_right_rule) + new_left_rule = "".join(new_right_rule).strip() final_right_rule = "" if rule_match is None else _correct_bracket(right_rule, right_name) - return " ".join([new_left_rule, operator, final_right_rule]) + return " ".join([new_left_rule, operator, final_right_rule]).strip() def _gene_rule_logical(gpr_expression: str, level: int = 0) -> str: @@ -75,10 +75,10 @@ def _gene_rule_logical(gpr_expression: str, level: int = 0) -> str: loc_r = gpr_expression.index(")") except ValueError: if "and" in gpr_expression: - gpr_expression = gpr_expression.replace("and", ",") + gpr_expression = gpr_expression.replace(" and ", ", ") return "min{" + gpr_expression + "}" elif "or" in gpr_expression: - gpr_expression = gpr_expression.replace("or", ",") + gpr_expression = gpr_expression.replace(" or ", ", ") return "max{" + gpr_expression + "}" else: gpr_expression = gpr_expression.replace("[", "") From 675a26bb4e07a37ebc9822d543e85428ae75d980 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:10:46 -0600 Subject: [PATCH 124/265] refactor: reduce extraneous function usage --- main/como/create_context_specific_model.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 96ca2cae..91ed0c6b 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -104,14 +104,6 @@ def _gene_rule_logical(gpr_expression: str, level: int = 0) -> str: return expression_out -def _gene_rule_evaluable(expression_in: str) -> str: - """Make expression rule evaluable.""" - gene_reaction_by_rule = _gene_rule_logical(expression_in) - gene_reaction_by_rule = gene_reaction_by_rule.replace("{", "(") - gene_reaction_by_rule = gene_reaction_by_rule.replace("}", ")") - - return gene_reaction_by_rule - def _set_boundaries(model: cobra.Model, bound_rxns: list, bound_lb, bound_ub) -> tuple[cobra.Model, list]: all_rxns = model.reactions # get all reactions From 618edc731835f3d3058d129e1dd26a74509d1e09 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:10:57 -0600 Subject: [PATCH 125/265] style: ruff whitespace formatting --- main/como/create_context_specific_model.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 91ed0c6b..9d8e73b6 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -104,11 +104,12 @@ def _gene_rule_logical(gpr_expression: str, level: int = 0) -> str: return expression_out - -def _set_boundaries(model: cobra.Model, bound_rxns: list, bound_lb, bound_ub) -> tuple[cobra.Model, list]: - all_rxns = model.reactions # get all reactions - bound_rm_rxns = [] - +def _set_boundaries( + model: cobra.Model, + boundary_reactions: list[str], + lower_bounds: list[float], + upper_bounds: list[float], +) -> cobra.Model: # get boundary reactions exchange_rxns = [rxn.id for rxn in all_rxns if re.search("EX_", rxn.id)] sink_rxns = [rxn.id for rxn in all_rxns if re.search("sink_", rxn.id)] From 70371fee29caca2f382b4660340ad1e686eaae84 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:11:23 -0600 Subject: [PATCH 126/265] refactor: remove extraneous variable --- main/como/create_context_specific_model.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 9d8e73b6..c267587b 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -111,9 +111,9 @@ def _set_boundaries( upper_bounds: list[float], ) -> cobra.Model: # get boundary reactions - exchange_rxns = [rxn.id for rxn in all_rxns if re.search("EX_", rxn.id)] - sink_rxns = [rxn.id for rxn in all_rxns if re.search("sink_", rxn.id)] - demand_rxns = [rxn.id for rxn in all_rxns if re.search("DM_", rxn.id)] + exchange_rxns = [rxn.id for rxn in model.reactions if re.search("EX_", rxn.id)] + sink_rxns = [rxn.id for rxn in model.reactions if re.search("sink_", rxn.id)] + demand_rxns = [rxn.id for rxn in model.reactions if re.search("DM_", rxn.id)] # Allows all boundary reactions to be used if none are given allow_all_boundary_rxns = not bound_rxns From cd36b5ed39489a0d563d0fcf1f376aa7c085b2ab Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:11:53 -0600 Subject: [PATCH 127/265] refactor: pythonic if-statement calculation --- main/como/create_context_specific_model.py | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index c267587b..7541d4c3 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -121,25 +121,18 @@ def _set_boundaries( # close sinks and demands not in boundary reactions unless no boundary reactions were given if not allow_all_boundary_rxns: for i, rxn in enumerate(sink_rxns): # set sinks to 0 - if rxn not in bound_rxns: # only allow sink accumulation - getattr(model.reactions, rxn).lower_bounds = 0 - getattr(model.reactions, rxn).upper_bounds = 1000 - else: # set from file - getattr(model.reactions, rxn).lower_bounds = bound_lb[i] - getattr(model.reactions, rxn).upper_bounds = bound_ub[i] + getattr(model.reactions, rxn).lower_bounds = lower_bounds[i] if rxn in boundary_reactions else 0 + getattr(model.reactions, rxn).upper_bounds = upper_bounds[i] if rxn in boundary_reactions else 1000 for i, rxn in enumerate(demand_rxns): getattr(model.reactions, rxn).lower_bounds = 0 - getattr(model.reactions, rxn).upper_bounds = bound_ub[i] if rxn in bound_rxns else 0 + getattr(model.reactions, rxn).upper_bounds = upper_bounds[i] if rxn in boundary_reactions else 0 # Reaction media medium = model.medium # get reaction media to modify for rxn in exchange_rxns: # open exchanges from exchange file, close unspecified exchanges - if rxn not in bound_rxns: - medium[rxn] = 0.0 - else: - medium[rxn] = -float(bound_lb[bound_rxns.index(rxn)]) - model.medium = medium # set new media + medium[rxn] = -float(lower_bounds[boundary_reactions.index(rxn)]) if rxn in boundary_reactions else 0.0 + model.medium = medium return model, bound_rm_rxns From d5f1fdffba9f4665c0186f1529e43a828d427a58 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:12:14 -0600 Subject: [PATCH 128/265] refactor: remove extraneous comment + variables --- main/como/create_context_specific_model.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 7541d4c3..e80ddc4f 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -116,7 +116,7 @@ def _set_boundaries( demand_rxns = [rxn.id for rxn in model.reactions if re.search("DM_", rxn.id)] # Allows all boundary reactions to be used if none are given - allow_all_boundary_rxns = not bound_rxns + allow_all_boundary_rxns = not boundary_reactions # close sinks and demands not in boundary reactions unless no boundary reactions were given if not allow_all_boundary_rxns: @@ -129,12 +129,12 @@ def _set_boundaries( getattr(model.reactions, rxn).upper_bounds = upper_bounds[i] if rxn in boundary_reactions else 0 # Reaction media - medium = model.medium # get reaction media to modify + medium = model.medium for rxn in exchange_rxns: # open exchanges from exchange file, close unspecified exchanges medium[rxn] = -float(lower_bounds[boundary_reactions.index(rxn)]) if rxn in boundary_reactions else 0.0 model.medium = medium - return model, bound_rm_rxns + return model def _feasibility_test(model_cobra: cobra.Model, step: str): From b586e251e4e1d314df974920d7c00f07420a08fa Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:12:56 -0600 Subject: [PATCH 129/265] style: more verbose parameter names --- main/como/create_context_specific_model.py | 40 +++++++++++++--------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index e80ddc4f..3f62d9ef 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -165,7 +165,7 @@ def _feasibility_test(model_cobra: cobra.Model, step: str): return incon_rxns, model_cobra_rm -def _build_with_gimme(cobra_model, s_matrix, lb, ub, idx_objective, expr_vector): +def _build_with_gimme(cobra_model, s_matrix, lower_bounds, upper_bounds, idx_objective, expr_vector): # `Becker and Palsson (2008). Context-specific metabolic networks are # consistent with experiments. PLoS Comput. Biol. 4, e1000082.` properties = GIMMEProperties( @@ -175,23 +175,23 @@ def _build_with_gimme(cobra_model, s_matrix, lb, ub, idx_objective, expr_vector) preprocess=True, flux_threshold=0.9, ) - algorithm = GIMME(s_matrix, lb, ub, properties) + algorithm = GIMME(s_matrix, lower_bounds, upper_bounds, properties) gene_activity = algorithm.run() context_cobra_model = cobra_model.copy() - r_ids = [r.id for r in context_cobra_model.reactions] - to_remove_ids = [r_ids[r] for r in np.where(gene_activity == 0)[0]] + reaction_ids = [r.id for r in context_cobra_model.reactions] + to_remove_ids = [reaction_ids[r] for r in np.where(gene_activity == 0)[0]] context_cobra_model.remove_reactions(to_remove_ids, True) - r_ids = [r.id for r in context_cobra_model.reactions] psol = pfba(context_cobra_model) # noqa: F841 + # reaction_ids = [r.id for r in context_cobra_model.reactions] # psol = context_cobra_model.optimize() - # to_remove_ids = [r_ids[r] for r in np.where(abs(psol.fluxes) < 1e-8)[0]] + # to_remove_ids = [reaction_ids[r] for r in np.where(abs(psol.fluxes) < 1e-8)[0]] # context_cobra_model.remove_reactions(to_remove_ids, True) return context_cobra_model -def _build_with_fastcore(cobra_model, s_matrix, lb, ub, exp_idx_list, solver): +def _build_with_fastcore(cobra_model, s_matrix, lower_bounds, upper_bounds, exp_idx_list, solver): # 'Vlassis, Pacheco, Sauter (2014). Fast reconstruction of compact # context-specific metabolic network models. PLoS Comput. Biol. 10, # e1003424.' @@ -202,7 +202,7 @@ def _build_with_fastcore(cobra_model, s_matrix, lb, ub, exp_idx_list, solver): logger.debug("Creating feasible model") incon_rxns, cobra_model = _feasibility_test(cobra_model, "other") properties = FastcoreProperties(core=exp_idx_list, solver=solver) - algorithm = FASTcore(s_matrix, lb, ub, properties) + algorithm = FASTcore(s_matrix, lower_bounds, upper_bounds, properties) context_rxns = algorithm.fastcore() context_cobra_model = cobra_model.copy() r_ids = [r.id for r in context_cobra_model.reactions] @@ -215,22 +215,22 @@ def _build_with_fastcore(cobra_model, s_matrix, lb, ub, exp_idx_list, solver): def _build_with_imat( cobra_model: cobra.Model, s_matrix: npt.NDArray, - lb: Sequence[float], - ub: Sequence[float], + lower_bounds: Sequence[float], + upper_bounds: Sequence[float], expr_vector: npt.NDArray, - expr_thesh: tuple[float, float], + expr_thresh: tuple[float, float], force_gene_ids: Sequence[int], solver: str, ) -> (cobra.Model, pd.DataFrame): expr_vector = np.array(expr_vector) properties = IMATProperties( exp_vector=expr_vector, - exp_thresholds=expr_thesh, + exp_thresholds=expr_thresh, core=force_gene_ids, epsilon=0.01, solver=solver.upper(), ) - algorithm = IMAT(s_matrix, np.array(lb), np.array(ub), properties) + algorithm = IMAT(s_matrix, np.array(lower_bounds), np.array(upper_bounds), properties) context_rxns: npt.NDArray = algorithm.run() fluxes: pd.Series = algorithm.sol.to_series() context_cobra_model = cobra_model.copy() @@ -249,7 +249,15 @@ def _build_with_imat( return context_cobra_model, flux_df -def _build_with_tinit(cobra_model: cobra.Model, s_matrix, lb, ub, expr_vector, solver, idx_force) -> Model: +def _build_with_tinit( + cobra_model: cobra.Model, + s_matrix, + lower_bounds, + upper_bounds, + expr_vector, + solver, + idx_force, +) -> Model: properties = tINITProperties( reactions_scores=expr_vector, solver=solver, @@ -258,10 +266,10 @@ def _build_with_tinit(cobra_model: cobra.Model, s_matrix, lb, ub, expr_vector, s allow_excretion=False, no_reverse_loops=True, ) - algorithm = tINIT(s_matrix, lb, ub, properties) + algorithm = tINIT(s_matrix, lower_bounds, upper_bounds, properties) algorithm.preprocessing() algorithm.build_problem() - raise NotImplementedError("tINIT is not yet implemented") + _log_and_raise_error("tINIT is not yet implemented.", error=NotImplementedError, level=LogLevel.CRITICAL) def _map_expression_to_reaction( From 498e84a8c5810f9de91fcdce960dbc1d32bdf39f Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:13:08 -0600 Subject: [PATCH 130/265] refactor: async usage where possible --- main/como/create_context_specific_model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 3f62d9ef..241ee2ee 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -272,7 +272,7 @@ def _build_with_tinit( _log_and_raise_error("tINIT is not yet implemented.", error=NotImplementedError, level=LogLevel.CRITICAL) -def _map_expression_to_reaction( +async def _map_expression_to_reaction( model_cobra, gene_expression_file, recon_algorithm: Algorithm, From 1668b35f31a5e0f7ddd257738176e867f35f133b Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:13:16 -0600 Subject: [PATCH 131/265] refactor: type hinting --- main/como/create_context_specific_model.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 241ee2ee..6bdb4eae 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -276,9 +276,9 @@ async def _map_expression_to_reaction( model_cobra, gene_expression_file, recon_algorithm: Algorithm, - low_thresh=None, - high_thresh=None, -): + low_thresh: float, + high_thresh: float, +) -> collections.OrderedDict[str, int]: """Map gene ids to a reaction based on GPR (gene to protein to reaction) association rules. These rules should be defined in the general genome-scale metabolic model From f162b94ac7d73dff131873750d58a274f325be21 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:13:40 -0600 Subject: [PATCH 132/265] refactor: pythonic collection of gene activity --- main/como/create_context_specific_model.py | 23 +++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 6bdb4eae..0bd84b99 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -283,17 +283,18 @@ async def _map_expression_to_reaction( These rules should be defined in the general genome-scale metabolic model """ - expression_data = pd.read_csv(gene_expression_file) - gene_expressions = split_gene_expression_data(expression_data, recon_algorithm=recon_algorithm) - expression_rxns = collections.OrderedDict() - - unknown_val = 1 - if recon_algorithm in {Algorithm.IMAT, Algorithm.TINIT}: - unknown_val = np.mean([low_thresh, high_thresh]) # put unknowns in mid bin - elif recon_algorithm == Algorithm.GIMME: - unknown_val = -1 - elif recon_algorithm == Algorithm.FASTCORE: - unknown_val = 0 + gene_activity = split_gene_expression_data(await _read_file(gene_expression_file), recon_algorithm=recon_algorithm) + reaction_expression = collections.OrderedDict() + + # fmt: off + # Define a default expression value if a gene ID is not found + default_expression = ( + np.mean([low_thresh, high_thresh]) if recon_algorithm in {Algorithm.IMAT, Algorithm.TINIT} + else -1 if recon_algorithm in {Algorithm.GIMME} + else 0 if recon_algorithm in {Algorithm.FASTCORE} + else 1 + ) + # fmt: on error_count = 0 for rxn in model_cobra.reactions: From 52f335f2e609d18f714d6084aba1f2cf15f1c4b7 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:24:31 -0600 Subject: [PATCH 133/265] fix: update mapping process to be more readable --- main/como/create_context_specific_model.py | 583 +++++++++------------ 1 file changed, 261 insertions(+), 322 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 0bd84b99..3d123c40 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -298,46 +298,57 @@ async def _map_expression_to_reaction( error_count = 0 for rxn in model_cobra.reactions: + rxn: cobra.Reaction gene_reaction_rule = _correct_bracket(rxn.gene_reaction_rule, rxn.gene_name_reaction_rule) - gene_ids = re.findall(r"\d+", gene_reaction_rule) - expression_rxns[rxn.id] = unknown_val - if gene_reaction_rule.strip() == "": + if gene_reaction_rule == "": continue - for gid in gene_ids: - if gid in gene_expressions.index: - rep_val = f' {gene_expressions.at[gid, "active"]} ' - else: - rep_val = f" {unknown_val!s} " - gene_reaction_rule = f" {gene_reaction_rule} " # pad white space to prevent gene matches inside floats - gene_reaction_rule = gene_reaction_rule.replace(f" {gid} ", rep_val, 1) - try: - gene_reaction_by_rule = _gene_rule_evaluable(gene_reaction_rule) - gene_reaction_by_rule = gene_reaction_by_rule.strip() - expression_rxns[rxn.id] = ast.literal_eval(gene_reaction_by_rule) - except BaseException: + gene_ids = re.findall(r"\d+", gene_reaction_rule) + reaction_expression[rxn.id] = default_expression + for gene_id in gene_ids: + activity = ( + f"{gene_activity.at[gene_id, 'active']}" + if gene_id in gene_activity.index + else f"{default_expression!s}" + ) + # replace gene_id with activity, using optional whitespace before and after the gene id + # Do not replace the whitespace (if it exists) before and after the gene ID + gene_reaction_rule = re.sub( + pattern=rf"(? _BuildResults: """Seed a context specific reference_model. @@ -346,7 +357,6 @@ def _build_model( # noqa: C901 file. Metabolite exchange (media), sinks, and demands are determined from exchanges file. Reactions can also be force excluded even if they meet GPR association requirements using the force exclude file. """ - config = Config() reference_model: cobra.Model match general_model_file.suffix: case ".mat": @@ -356,188 +366,230 @@ def _build_model( # noqa: C901 case ".json": reference_model = cobra.io.load_json_model(general_model_file) case _: - raise NameError( - f"Reference reference_model format must be .xml, .mat, or .json, found '{general_model_file.suffix}'" + _log_and_raise_error( + f"Reference model format must be .xml, .mat, or .json; found '{general_model_file.suffix}'", + error=ValueError, + level=LogLevel.ERROR, ) - reference_model.objective = {getattr(reference_model.reactions, objective): 1} # set objective - - if objective not in force_rxns: - force_rxns.append(objective) + reference_model.objective = {getattr(reference_model.reactions, objective): 1} + if objective not in force_reactions: + force_reactions.append(objective) - # set boundaries - reference_model, bound_rm_rxns = _set_boundaries(reference_model, bound_rxns, bound_lb, bound_ub) - - # set solver + reference_model = _set_boundaries(reference_model, boundary_reactions, lower_bounds, upper_bounds) reference_model.solver = solver.lower() # check number of unsolvable reactions for reference model under media assumptions - # incon_rxns, cobra_model = _feasibility_test(cobra_model, "before_seeding") - incon_rxns = [] - + # inconsistent_reactions, cobra_model = _feasibility_test(cobra_model, "before_seeding") + inconsistent_reactions = [] s_matrix = cobra.util.array.create_stoichiometric_matrix(reference_model, array_type="dense") - lb = [] - ub = [] - rx_names = [] + lower_bounds = [] + upper_bounds = [] + reaction_ids = [] for reaction in reference_model.reactions: - lb.append(reaction.lower_bound) - ub.append(reaction.upper_bound) - rx_names.append(reaction.id) + lower_bounds.append(reaction.lower_bound) + upper_bounds.append(reaction.upper_bound) + reaction_ids.append(reaction.id) # get expressed reactions - expression_rxns, expr_vector = _map_expression_to_reaction( + reaction_expression: collections.OrderedDict[str, int] = await _map_expression_to_reaction( reference_model, gene_expression_file, recon_algorithm, high_thresh=high_thresh, low_thresh=low_thresh, ) + expression_vector: npt.NDArray[np.int32] = np.array(list(reaction_expression.values()), dtype=np.int32) - for rxn in force_rxns: - if rxn not in rx_names: + for rxn in force_reactions: + if rxn not in reaction_ids: logger.warning( f"The force reaction '{rxn}' was not found in the general reference_model. " f"Check BiGG, or the relevant database for your general reference_model, for synonyms." ) # collect list of reactions that are infeasible but active in expression data or user defined - infeas_exp_rxns = [] - infeas_force_rxns = [] - infeas_exp_cnt = 0 - infeas_force_cnt = 0 + infeasible_expression_reactions = [] + infeasible_force_reactions = [] - for idx, rxn in enumerate(expression_rxns): + for i, rxn in enumerate(reaction_expression): # log reactions in expressed and force lists that are infeasible that the user may wish to review - if rxn in incon_rxns and expr_vector[idx] == 1: - infeas_exp_cnt += 1 - infeas_exp_rxns.append(rxn) - if rxn in incon_rxns and rxn in force_rxns: - infeas_force_cnt += 1 - infeas_force_rxns.append(rxn) - - # make changes to expressed reactions base on user defined force/exclude reactions - # TODO: if not using bound reactions file, add two sets of exchange reactions to be put in either low or mid bin - - if rxn in force_rxns: - expr_vector[idx] = high_thresh + 0.1 if recon_algorithm.value in {"TINIT", "IMAT"} else 1 - if rxn in incon_rxns or rxn in exclude_rxns: - expr_vector[idx] = low_thresh - 0.1 if recon_algorithm.value in {"TINIT", "IMAT"} else 0 - - idx_obj = rx_names.index(objective) - idx_force = [rx_names.index(rxn) for rxn in force_rxns if rxn in rx_names] - exp_idx_list = [i for (i, val) in enumerate(expr_vector) if val > 0] # type: ignore - exp_thresh = (low_thresh, high_thresh) - - if recon_algorithm == Algorithm.GIMME: - context_model_cobra = _build_with_gimme(reference_model, s_matrix, lb, ub, idx_obj, expr_vector) - elif recon_algorithm == Algorithm.FASTCORE: - context_model_cobra = _build_with_fastcore(reference_model, s_matrix, lb, ub, exp_idx_list, solver) - elif recon_algorithm == Algorithm.IMAT: - context_model_cobra: cobra.Model - context_model_cobra, flux_df = _build_with_imat( - reference_model, - s_matrix, - lb, - ub, - expr_vector, - exp_thresh, - idx_force, - solver=solver, - ) - imat_reactions = flux_df.rxn - model_reactions = [reaction.id for reaction in context_model_cobra.reactions] - reaction_intersections = set(imat_reactions).intersection(model_reactions) - flux_df = flux_df[~flux_df["rxn"].isin(reaction_intersections)] - flux_df.to_csv(config.data_dir / "results" / context_name / f"{recon_algorithm.value}_flux.csv") - elif recon_algorithm == Algorithm.TINIT: - context_model_cobra = _build_with_tinit(reference_model, s_matrix, lb, ub, expr_vector, solver, idx_force) - - incon_rxns_cs = [] - incon_df = pd.DataFrame({"general_infeasible_rxns": list(incon_rxns)}) - infeas_exp_df = pd.DataFrame({"expressed_infeasible_rxns": infeas_exp_rxns}) - infeas_force_df = pd.DataFrame({"infeasible_rxns_in_force_list": infeas_exp_rxns}) - incon_df_cs = pd.DataFrame({"infeasible_rxns_from_seeding": list(incon_rxns_cs)}) - infeasible_df = pd.concat([incon_df, infeas_exp_df, infeas_force_df, incon_df_cs], ignore_index=True, axis=1) - infeasible_df.columns = ["InfeasRxns", "ExpressedInfeasRxns", "ForceInfeasRxns", "ContextInfeasRxns"] + if rxn in inconsistent_reactions and expression_vector[i] == 1: + infeasible_expression_reactions.append(rxn) + if rxn in inconsistent_reactions and rxn in force_reactions: + infeasible_force_reactions.append(rxn) + + if rxn in force_reactions: + expression_vector[i] = high_thresh + 0.1 if recon_algorithm in {Algorithm.TINIT, Algorithm.IMAT} else 1 + if rxn in inconsistent_reactions or rxn in exclude_reactions: + expression_vector[i] = low_thresh - 0.1 if recon_algorithm in {Algorithm.TINIT, Algorithm.IMAT} else 0 + + objective_index = reaction_ids.index(objective) + force_reaction_indices = [reaction_ids.index(rxn) for rxn in force_reactions if rxn in reaction_ids] + expression_vector_indices = [i for (i, val) in enumerate(expression_vector) if val > 0] # type: ignore + expression_threshold = (low_thresh, high_thresh) + + match recon_algorithm: + case Algorithm.GIMME: + context_model_cobra = _build_with_gimme( + cobra_model=reference_model, + s_matrix=s_matrix, + lower_bounds=lower_bounds, + upper_bounds=upper_bounds, + idx_objective=objective_index, + expr_vector=expression_vector, + ) + case Algorithm.FASTCORE: + context_model_cobra = _build_with_fastcore( + cobra_model=reference_model, + s_matrix=s_matrix, + lower_bounds=lower_bounds, + upper_bounds=upper_bounds, + exp_idx_list=expression_vector_indices, + solver=solver, + ) + case Algorithm.IMAT: + context_model_cobra: cobra.Model + context_model_cobra, flux_df = _build_with_imat( + cobra_model=reference_model, + s_matrix=s_matrix, + lower_bounds=lower_bounds, + upper_bounds=upper_bounds, + expr_vector=expression_vector, + expr_thresh=expression_threshold, + force_gene_ids=force_reaction_indices, + solver=solver, + ) + imat_reactions = flux_df.rxn + model_reactions = [reaction.id for reaction in context_model_cobra.reactions] + reaction_intersections = set(imat_reactions).intersection(model_reactions) + flux_df: pd.DataFrame = flux_df[~flux_df["rxn"].isin(reaction_intersections)] + flux_df.dropna(inplace=True) + flux_df.to_csv(output_flux_result_filepath) + case Algorithm.TINIT: + context_model_cobra = _build_with_tinit( + cobra_model=reference_model, + s_matrix=s_matrix, + lower_bounds=lower_bounds, + upper_bounds=upper_bounds, + expr_vector=expression_vector, + solver=solver, + idx_force=force_reaction_indices, + ) + case _: + _log_and_raise_error( + ( + f"Reconstruction algorithm must be {Algorithm.GIMME.value}, " + f"{Algorithm.FASTCORE.value}, {Algorithm.IMAT.value}, or {Algorithm.TINIT.value}. " + f"Got: {recon_algorithm.value}" + ), + error=ValueError, + level=LogLevel.ERROR, + ) + + inconsistent_and_infeasible_reactions: pd.DataFrame = pd.concat( + [ + pd.DataFrame({"infeasible_reactions": inconsistent_reactions}), + pd.DataFrame({"expressed_infeasible_reactions": infeasible_expression_reactions}), + pd.DataFrame({"infeasible_force_reactions": infeasible_force_reactions}), + pd.DataFrame({"infeasible_context_reactions": []}), + ], + ignore_index=True, + axis=0, + ) + print(inconsistent_and_infeasible_reactions) return _BuildResults( model=context_model_cobra, - expression_index_list=exp_idx_list, - infeasible_reactions=infeasible_df, + expression_index_list=expression_vector_indices, + infeasible_reactions=inconsistent_and_infeasible_reactions, ) -def _create_df(path: Path) -> pd.DataFrame: +async def _create_df(path: Path) -> pd.DataFrame: match path.suffix: - case ".csv": - df = pd.read_csv(path, header=0, sep=",") - case ".tsv": - df = pd.read_csv(path, header=0, sep="\t") + case ".csv" | ".tsv": + df = await _read_file(path, header=0, sep="," if path.suffix == ".csv" else "\t") case ".xlsx" | ".xls": - df = pd.read_excel(path, header=0) + df = await _read_file(path, header=0) case _: - raise FileNotFoundError(f"File not found! Must be a csv, tsv, or Excel file. Searching for: {path}") + _log_and_raise_error( + f"File not found! Must be a csv, tsv, or Excel file. Searching for: {path}", + error=FileNotFoundError, + level=LogLevel.ERROR, + ) df.columns = [c.lower() for c in df.columns] return df -def _collect_boundary_reactions(path: Path) -> _BoundaryReactions: - df = _create_df(path) +async def _collect_boundary_reactions(path: Path) -> _BoundaryReactions: + df: pd.DataFrame = await _create_df(path) for column in df.columns: if column not in [ "boundary", - "reaction", "abbreviation", "compartment", "minimum reaction rate", "maximum reaction rate", ]: - raise ValueError( - f"Boundary reactions file must have columns named 'Reaction', 'Abbreviation', 'Compartment', " - f"'Minimum Reaction Rate', and 'Maximum Reaction Rate'. Found: {column}" + _log_and_raise_error( + ( + f"Boundary reactions file must have columns named 'Reaction', 'Abbreviation', 'Compartment', " + f"'Minimum Reaction Rate', and 'Maximum Reaction Rate'. Found: {column}" + ), + error=ValueError, + level=LogLevel.ERROR, ) reactions: list[str] = [""] * len(df) - boundary_type: list[str] = df["reaction"].tolist() - reaction_abbreviation: list[str] = df["abbreviation"].tolist() - reaction_compartment: list[str] = df["compartment"].tolist() - lower_bound = df["minimum reaction rate"].tolist() - upper_bound = df["maximum reaction rate"].tolist() + boundary_type: list[str] = df["boundary"].tolist() + reaction_abbreviation: list[str] = df["abbreviation"].astype(str).tolist() + reaction_compartment: list[str] = df["compartment"].astype(str).tolist() boundary_map = {"exchange": "EX", "demand": "DM", "sink": "SK"} for i in range(len(boundary_type)): boundary: str = boundary_type[i].lower() if boundary not in boundary_map: - raise ValueError(f"Boundary reaction type must be 'Exchange', 'Demand', or 'Sink'. Found: {boundary[i]}") + _log_and_raise_error( + f"Boundary reaction type must be 'Exchange', 'Demand', or 'Sink'. Found: {boundary}", + error=ValueError, + level=LogLevel.ERROR, + ) - shorthand_compartment = Compartments.get(reaction_compartment[i]) + shorthand_compartment = CobraCompartments.get_shorthand(reaction_compartment[i]) reactions[i] = f"{boundary_map.get(boundary)}_{reaction_abbreviation[i]}[{shorthand_compartment}]" return _BoundaryReactions( reactions=reactions, - lower_bounds=lower_bound, - upper_bounds=upper_bound, + lower_bounds=df["minimum reaction rate"].tolist(), + upper_bounds=df["maximum reaction rate"].tolist(), ) -def _write_model_to_disk( +async def _write_model_to_disk( model: cobra.Model, output_directory: Path, context_name: str, output_filetypes: list[str], algorithm: Algorithm, ) -> None: + output_directory.mkdir(parents=True, exist_ok=True) if "mat" in output_filetypes: - cobra.io.save_matlab_model(model, output_directory / f"{context_name}_SpecificModel_{algorithm.value}.mat") - if "xml" in output_filetypes: - cobra.io.write_sbml_model(model, output_directory / f"{context_name}_SpecificModel_{algorithm.value}.xml") + cobra.io.save_matlab_model(model, (output_directory / f"{context_name}_SpecificModel_{algorithm.value}.mat")) if "json" in output_filetypes: - cobra.io.save_json_model(model, output_directory / f"{context_name}_SpecificModel_{algorithm.value}.json") + cobra.io.save_json_model(model, (output_directory / f"{context_name}_SpecificModel_{algorithm.value}.json")) + if "xml" in output_filetypes: + cobra.io.write_sbml_model(model, (output_directory / f"{context_name}_SpecificModel_{algorithm.value}.xml")) -def create_context_specific_model( # noqa: C901 +async def create_context_specific_model( # noqa: C901 context_name: str, reference_model: Path, - genes_file: Path, + active_genes_filepath: Path, + output_infeasible_reactions_filepath: Path, + output_model_dirpath: Path, + output_flux_result_filepath: Path, + output_filetypes: list[str] | None = None, + output_fastcore_expression_index_filepath: Path | None = None, objective: str = "biomass_reaction", boundary_rxns_filepath: str | Path | None = None, exclude_rxns_filepath: str | Path | None = None, @@ -546,233 +598,120 @@ def create_context_specific_model( # noqa: C901 low_threshold: float = -5, high_threshold: float = -3, solver: Solver = Solver.GLPK, - output_filetypes: list[str] | None = None, + log_level: LogLevel = LogLevel.INFO, + log_location: str | TextIOWrapper = sys.stderr, ): """Create a context-specific model using the provided data.""" + _set_up_logging(level=log_level, location=log_location) if not reference_model.exists(): - raise FileNotFoundError(f"Reference model not found at {reference_model}") - if not genes_file.exists(): - raise FileNotFoundError(f"Active genes file not found at {genes_file}") - if output_filetypes is None: - output_filetypes = ["mat"] + _log_and_raise_error( + f"Reference model not found at {reference_model}", + error=FileNotFoundError, + level=LogLevel.ERROR, + ) + if not active_genes_filepath.exists(): + _log_and_raise_error( + f"Active genes file not found at {active_genes_filepath}", + error=FileNotFoundError, + level=LogLevel.ERROR, + ) + if algorithm == Algorithm.FASTCORE and not output_fastcore_expression_index_filepath: + _log_and_raise_error( + "The fastcore expression index output filepath must be provided", + error=ValueError, + level=LogLevel.ERROR, + ) + if boundary_rxns_filepath and not boundary_rxns_filepath.exists(): + _log_and_raise_error( + f"Boundary reactions file not found at {boundary_rxns_filepath}", + error=FileNotFoundError, + level=LogLevel.ERROR, + ) + output_filetypes = ["mat"] if output_filetypes is None else output_filetypes for output_type in output_filetypes: if output_type not in {"xml", "mat", "json"}: - raise ValueError(f"Output file type {output_type} not recognized. Must be one of: 'xml', 'mat', 'json'") + _log_and_raise_error( + f"Output file type {output_type} not recognized. Must be one of: 'xml', 'mat', 'json'", + error=ValueError, + level=LogLevel.ERROR, + ) if algorithm not in Algorithm: - raise ValueError(f"Algorithm {algorithm} not supported. Use one of {', '.join(a.value for a in Algorithm)}") + _log_and_raise_error( + f"Algorithm {algorithm} not supported. Use one of {', '.join(a.value for a in Algorithm)}", + error=ValueError, + level=LogLevel.ERROR, + ) if solver not in Solver: - raise ValueError(f"Solver '{solver}' not supported. Use one of {', '.join(s.value for s in Solver)}") + _log_and_raise_error( + f"Solver '{solver}' not supported. Use one of {', '.join(s.value for s in Solver)}", + error=ValueError, + level=LogLevel.ERROR, + ) if boundary_rxns_filepath: - boundary_reactions = _collect_boundary_reactions(boundary_rxns_filepath) + boundary_reactions = await _collect_boundary_reactions(boundary_rxns_filepath) exclude_rxns: list[str] = [] if exclude_rxns_filepath: exclude_rxns_filepath: Path = Path(exclude_rxns_filepath) - df = _create_df(exclude_rxns_filepath) + df = await _create_df(exclude_rxns_filepath) if "abbreviation" not in df.columns: - raise ValueError("The exclude reactions file should have a single column with a header named Abbreviation") + _log_and_raise_error( + "The exclude reactions file should have a single column with a header named Abbreviation", + error=ValueError, + level=LogLevel.ERROR, + ) exclude_rxns = df["abbreviation"].tolist() force_rxns: list[str] = [] if force_rxns_filepath: force_rxns_filepath: Path = Path(force_rxns_filepath) - df = _create_df(force_rxns_filepath) + df = await _create_df(force_rxns_filepath) if "abbreviation" not in df.columns: - raise ValueError("The force reactions file should have a single column with a header named Abbreviation") + _log_and_raise_error( + "The force reactions file should have a single column with a header named Abbreviation", + error=ValueError, + level=LogLevel.ERROR, + ) force_rxns = df["abbreviation"].tolist() logger.info(f"Creating '{context_name}' model using '{algorithm.value}' reconstruction and '{solver.value}' solver") - build_results: _BuildResults = _build_model( - context_name=context_name, + build_results: _BuildResults = await _build_model( general_model_file=reference_model, - gene_expression_file=genes_file, + gene_expression_file=active_genes_filepath, recon_algorithm=algorithm, objective=objective, - bound_rxns=boundary_reactions.reactions, - bound_lb=boundary_reactions.lower_bounds, - bound_ub=boundary_reactions.upper_bounds, - exclude_rxns=exclude_rxns, - force_rxns=force_rxns, + boundary_reactions=boundary_reactions.reactions, + exclude_reactions=exclude_rxns, + force_reactions=force_rxns, + lower_bounds=boundary_reactions.lower_bounds, + upper_bounds=boundary_reactions.upper_bounds, solver=solver.value.lower(), low_thresh=low_threshold, high_thresh=high_threshold, + output_flux_result_filepath=output_flux_result_filepath, ) - config = Config() - build_results.infeasible_reactions.to_csv( - config.result_dir / context_name / f"{context_name}_infeasible_rxns.csv", index=False - ) + build_results.infeasible_reactions.dropna(inplace=True) + build_results.infeasible_reactions.to_csv(output_infeasible_reactions_filepath, index=False) if algorithm == Algorithm.FASTCORE: - pd.DataFrame(build_results.expression_index_list).to_csv( - config.result_dir / context_name / f"{context_name}_core_rxns.csv", index=False - ) + fastcore_df = pd.DataFrame(build_results.expression_index_list) + fastcore_df.dropna(inplace=True) + fastcore_df.to_csv(output_fastcore_expression_index_filepath, index=False) - output_directory = config.result_dir / context_name - _write_model_to_disk( + await _write_model_to_disk( model=build_results.model, - output_directory=output_directory, + output_directory=output_model_dirpath, context_name=context_name, output_filetypes=output_filetypes, algorithm=algorithm, ) - logger.success(f"Saved output file to {output_directory}") - logger.info(f"Number of Genes: {len(build_results.model.genes):,}") - logger.info(f"Number of Metabolites: {len(build_results.model.metabolites):,}") - logger.info(f"Number of Reactions: {len(build_results.model.reactions):,}") - - -def _parse_args(): - parser = argparse.ArgumentParser( - prog="create_context_specific_model.py", - description="Seed a context-specific model from a list of expressed genes, a reference", - epilog="For additional help, please post questions/issues in the MADRID GitHub repo at " - "https://github.com/HelikarLab/MADRID or email babessell@gmail.com", - ) - parser.add_argument( - "-n", - "--context-name", - type=str, - required=True, - dest="context_name", - help="Name of context or context used consistent with outputs of merge_xomics.py.", - ) - parser.add_argument( - "-m", - "--reference-model-filepath", - type=str, - required=True, - dest="reference_model", - help="Name of Genome-scale metabolic model to seed the context model to. For example, the " - "GeneralModelUpdatedV2.mat, is a modified Recon3D model. We also provide iMM_madrid for mouse." - "OT can be .mat, .xml, or .json.", - ) - parser.add_argument( - "-g", - "--active-genes-filepath", - type=str, - required=True, - dest="active_genes_filepath", - help="Path to logical table of active genes output from merge_xomics.py called " - "ActiveGenes_contextName_Merged.csv. Should be in the corresponding context/context folder " - "inside /main/data/results/contextName/. The json file output from the function using " - "the context of interest as the key can be used here.", - ) - parser.add_argument( - "-o", - "--objective", - type=str, - default="biomass_reaction", - dest="objective", - help="Reaction ID of the objective function in the model. Generally a biomass function.", - ) - parser.add_argument( - "-b", - "--boundary-reactions-filepath", - type=str, - default=None, - dest="boundary_reactions_filepath", - help="Path to file contains the exchange (media), sink, and demand reactions which " - "the model should use to fulfill the reactions governed by transcriptomic and proteomics " - "data inputs. It must be a csv or xlsx with three columns: Rxn, Lowerbound, Upperbound. If not " - "specified, MADRID will allow ALL BOUNDARY REACTIONS THAT ARE OPEN IN THE REFERENCE MODEL " - "TO BE USED!", - ) - parser.add_argument( - "-x", - "--exclude-reactions-filepath", - type=str, - default=None, - dest="exclude_reactions_filepath", - help="Filepath to file that contains reactions which will be removed from active reactions " - "the model to use when seeding, even if considered active from transcriptomic and " - "proteomics data inputs. It must be a csv or xlsx with one column of reaction IDs consistent with " - "the reference model", - ) - parser.add_argument( - "-f", - "--force-reactions-filepath", - type=str, - default=None, - dest="force_reactions_filepath", - help="Filepath to file that contains reactions which will be added to active reactions for " - "the model to use when seeding (unless it causes the model to be unsolvable), regardless " - "of results of transcriptomic and proteomics data inputs. It must be a csv or xlsx with one " - "column of reaction IDs consistent with the reference model", - ) - parser.add_argument( - "-a", - "--algorithm", - type=str, - default="GIMME", - dest="recon_algorithm", - help="Algorithm used to seed context specific model to the Genome-scale model. " - "Can be either GIMME, FASTCORE, iMAT, or tINIT.", - ) - parser.add_argument( - "-lt", - "--low-threshold", - type=float, - default=-5, - dest="low_threshold", - help="Low to mid bin cutoff for iMAT solution", - ) - parser.add_argument( - "-ht", - "--high-threshold", - type=float, - default=-3, - dest="high_threshold", - help="Mid to high bin cutoff for iMAT solution", - ) - parser.add_argument( - "-s", - "--solver", - type=str, - default="glpk", - dest="solver", - help="Solver used to seed model and attempt to solve objective. Default is GLPK, also takes " - "GUROBI but you must mount a container license to the Docker to use. An academic license " - "can be obtained for free. See the README on the Github or Dockerhub for information on " - "mounting this license.", - ) - parser.add_argument( - "-t", - "--output-filetypes", - type=str, - nargs="+", - default="mat", - dest="output_filetypes", - help="Filetypes to save seeded model type. Can be either a string with one filetype such as " - "'xml' or multiple in the format \"['extension1', 'extension2', ... etc]\". If you want " - "to output in all 3 accepted formats, would be: \"['mat', 'xml', 'json']\" " - "Note the outer quotes required to be interpreted by cmd. This a string, not a python list", - ) - args = parser.parse_args() - args.output_filetypes = stringlist_to_list(args.output_filetypes) - args.solver = Solver.from_string(args.solver) # type: ignore - args.recon_algorithm = Algorithm.from_string(args.recon_algorithm) # type: ignore - return _Arguments(**vars(args)) - - -if __name__ == "__main__": - args = _parse_args() - create_context_specific_model( - context_name=args.context_name, - reference_model=args.reference_model, - genes_file=args.active_genes_filepath, - objective=args.objective, - boundary_rxns_filepath=args.boundary_reactions_filepath, - exclude_rxns_filepath=args.exclude_reactions_filepath, - force_rxns_filepath=args.force_reactions_filepath, - algorithm=args.recon_algorithm, - low_threshold=args.low_threshold, - high_threshold=args.high_threshold, - solver=args.solver, - output_filetypes=args.output_filetypes, - ) + logger.success(f"Saved metabolic model for context '{context_name}' to {output_model_dirpath}") + logger.debug(f"Number of Genes: {len(build_results.model.genes):,}") + logger.debug(f"Number of Metabolites: {len(build_results.model.metabolites):,}") + logger.debug(f"Number of Reactions: {len(build_results.model.reactions):,}") From eab0713be116ee0c8bf7fa9922b5f367294f89a7 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:24:49 -0600 Subject: [PATCH 134/265] refactor: import required modules --- main/como/combine_distributions.py | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index 595f4442..a09d0e8d 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -1,17 +1,24 @@ from __future__ import annotations -from collections.abc import Iterator -from dataclasses import dataclass, fields +import asyncio from pathlib import Path -from typing import Literal, NamedTuple +import aiofiles.os import numpy as np -import numpy.typing as npt import pandas as pd - +from loguru import logger + +from como.data_types import ( + GeneIdentifier, + SourceTypes, + _BatchEntry, + _BatchNames, + _CombineOmicsInput, + _InputMatrices, + _OutputCombinedSourceFilepath, + _SourceWeights, +) from como.graph import z_score_distribution as graph_zscore_distribution -from como.utils import _num_rows - class _IterableDataclass: def __iter__(self) -> Iterator[str]: From 23a01f02e017bf10161cb00b623c8427f34c7582 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:25:08 -0600 Subject: [PATCH 135/265] refactor: move dataclasses to data_types.py --- main/como/combine_distributions.py | 51 ++---------------------------- 1 file changed, 3 insertions(+), 48 deletions(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index a09d0e8d..f2b4425b 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -19,54 +19,9 @@ _SourceWeights, ) from como.graph import z_score_distribution as graph_zscore_distribution - -class _IterableDataclass: - def __iter__(self) -> Iterator[str]: - return iter(getattr(self, field.name) for field in fields(self)) # type: ignore - - -class _BatchEntry(NamedTuple): - batch_num: int - sample_names: list[str] - - -@dataclass -class _InputMatrices(_IterableDataclass): - trna: Path | pd.DataFrame | None - mrna: Path | pd.DataFrame | None - scrna: Path | pd.DataFrame | None - proteomics: Path | pd.DataFrame | None - - -@dataclass -class _BatchNames(_IterableDataclass): - trna: list[_BatchEntry] - mrna: list[_BatchEntry] - scrna: list[_BatchEntry] - proteomics: list[_BatchEntry] - - -@dataclass -class _SourceWeights(_IterableDataclass): - trna: int - mrna: int - scrna: int - proteomics: int - - -@dataclass -class _OutputCombinedSourceFilepath(_IterableDataclass): - trna: Path | None - mrna: Path | None - scrna: Path | None - proteomics: Path | None - - -@dataclass -class _CombineOmicsInput: - z_score_matrix: pd.DataFrame - type: Literal["totalrna", "mrna", "scrna", "proteomics"] - weight: int +from como.utils import ( + _num_columns, +) def _combine_batch_zdistro( From a207fcc64c5d50d23f50e9c758325189a673d7c1 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:25:58 -0600 Subject: [PATCH 136/265] refactor: make async functions --- main/como/combine_distributions.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index f2b4425b..37c01f27 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -24,8 +24,7 @@ ) -def _combine_batch_zdistro( - matrix: pd.DataFrame, +async def _combine_z_distribution_for_batch( context_name: str, batch_num: int, output_png_filepath: Path, @@ -73,8 +72,8 @@ def weighted_z(x: npt.NDArray[float], floor: int, ceiling: int) -> npt.NDArray[f return weighted_matrix -def _combine_context_zdistro( matrix: pd.DataFrame, +async def _combine_z_distribution_for_source( context_name: str, batch_num: int, num_replicates: int, @@ -203,7 +202,7 @@ def weighted_z( return combined_z_matrix -def _combine_zscores( +async def _begin_combining_distributions( context_name: str, input_matrices: _InputMatrices, batch_names: _BatchNames, From 5d918c5bea5aa18f2cfab631c8102db79e017a4a Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:26:57 -0600 Subject: [PATCH 137/265] refactor: simplify processing, use async --- main/como/combine_distributions.py | 84 ++++++++++-------------------- 1 file changed, 27 insertions(+), 57 deletions(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index 37c01f27..1155eb2c 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -213,71 +213,41 @@ async def _begin_combining_distributions( weighted_z_floor: int = -6, weighted_z_ceiling: int = 6, ): + logger.info(f"Starting to combine z-scores for context '{context_name}'") output_figure_dirpath.mkdir(parents=True, exist_ok=True) - source_name: list[str] = ["totalrna", "mrna", "scrna", "proteomics"] - zscore_results: list[_CombineOmicsInput] = [] - for matrix, source in zip(input_matrices, source_name): - matrix: pd.DataFrame | None = pd.read_csv(matrix) if isinstance(matrix, Path) else matrix - if matrix is not None: - if source == "totalrna": - batch_data = batch_names.trna - weight = source_weights.trna - output_filepath = output_filepaths.trna - elif source == "mrna": - batch_data = batch_names.mrna - weight = source_weights.mrna - output_filepath = output_filepaths.mrna - elif source == "scrna": - batch_data = batch_names.scrna - weight = source_weights.scrna - output_filepath = output_filepaths.scrna - elif source == "proteomics": - batch_data = batch_names.proteomics - weight = source_weights.proteomics - output_filepath = output_filepaths.proteomics - else: - raise ValueError(f"Invalid source; got '{source}', expected one of '{','.join(source_name)}'") + z_score_results: list[_CombineOmicsInput] = [] + for source, matrix in input_matrices: + if matrix is None: + logger.trace(f"Source '{source.value}' is None, skipping") + continue + if source not in SourceTypes: + logger.critical(f"Invalid source; got '{source.value}', expected 'trna', 'mrna', 'scrna', or 'proteomics'.") + raise ValueError("Invalid source") - replicate_count: list[int] = [] - merge_z_data = pd.DataFrame() - - batch: _BatchEntry - for batch in batch_data: - replicate_count.append(len(batch.sample_names)) - - batch_df: pd.DataFrame = matrix[["ensembl_gene_id", *batch.sample_names]] - # graph.z_score_distribution( - # batch_df, - # title=f"Z-Score Distribution for {context_name} - batch #{batch.batch_num} - {source}", - # output_png_filepath=output_figure_dirpath - # / f"{source}_batch{batch.batch_num}_zscore_distribution.png", - # ) - combine_z_matrix: pd.DataFrame = _combine_batch_zdistro( - matrix=batch_df, + batch_results = await asyncio.gather( + *[ + _combine_z_distribution_for_batch( context_name=context_name, - batch_num=batch.batch_num, - output_png_filepath=( - output_figure_dirpath - / f"combined_{source}_{context_name}_batch{batch.batch_num}_distribution.png" + batch=batch, + matrix=matrix[[GeneIdentifier.ENSEMBL_GENE_ID.value, *batch.sample_names]], + source=source, + output_combined_matrix_filepath=( + output_filepaths[source.value].parent + / f"{context_name}_{source.value}_batch{batch.batch_num}_combined_z_distribution_.csv" ), + output_figure_dirpath=output_figure_dirpath, weighted_z_floor=weighted_z_floor, weighted_z_ceiling=weighted_z_ceiling, ) - combine_z_matrix.columns = ["ensembl_gene_id", batch.batch_num] - merge_z_data = ( - combine_z_matrix - if merge_z_data.empty - else pd.merge(merge_z_data, combine_z_matrix, on="ensembl_gene_id", how="outer") - ) - combine_batches_zscore = _combine_context_zdistro( - matrix=merge_z_data, - context_name=context_name, - batch_num=batch.batch_num, - num_replicates=sum(replicate_count), - output_png_filepath=output_figure_dirpath / f"totalrna_{context_name}_combined_distribution.png", - weighted_z_floor=weighted_z_floor, - weighted_z_ceiling=weighted_z_ceiling, + for batch in batch_names[source.value] + ] + ) + + merged_batch_results = pd.DataFrame() + for df in batch_results: + merged_batch_results = ( + df if merged_batch_results.empty else merged_batch_results.merge(df, on="ensembl_gene_id", how="outer") ) zscore_results.append(_CombineOmicsInput(z_score_matrix=combine_batches_zscore, type=source, weight=weight)) # type: ignore combine_batches_zscore.to_csv(output_filepath, index=False) From 97cc2a9bce70a28887609c4805fa0813df9da61f Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:28:00 -0600 Subject: [PATCH 138/265] refactor: use relevant data types --- main/como/combine_distributions.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index 1155eb2c..f66bd253 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -26,10 +26,13 @@ async def _combine_z_distribution_for_batch( context_name: str, - batch_num: int, - output_png_filepath: Path, - weighted_z_floor: int = -6, - weighted_z_ceiling: int = 6, + batch: _BatchEntry, + matrix: pd.DataFrame, + source: SourceTypes, + output_combined_matrix_filepath: Path, + output_figure_dirpath: Path, + weighted_z_floor: int, + weighted_z_ceiling: int, ) -> pd.DataFrame: def weighted_z(x: npt.NDArray[float], floor: int, ceiling: int) -> npt.NDArray[float]: result = np.sum(x) / np.sqrt(len(x)) From aabcb8fd7d246bb4755c57013de7c04a9cd52112 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:28:25 -0600 Subject: [PATCH 139/265] refactor: pythonic approach to z score calculation --- main/como/combine_distributions.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index f66bd253..6a251180 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -34,9 +34,6 @@ async def _combine_z_distribution_for_batch( weighted_z_floor: int, weighted_z_ceiling: int, ) -> pd.DataFrame: - def weighted_z(x: npt.NDArray[float], floor: int, ceiling: int) -> npt.NDArray[float]: - result = np.sum(x) / np.sqrt(len(x)) - return np.clip(result, floor, ceiling) if _num_rows(matrix) < 2: return matrix @@ -48,6 +45,10 @@ def weighted_z(x: npt.NDArray[float], floor: int, ceiling: int) -> npt.NDArray[f floor=weighted_z_floor, ceiling=weighted_z_ceiling, ) + values = matrix.iloc[:, 1:].values + weighted_matrix = np.sum(values, axis=1) / np.sqrt(values.shape[1]) + weighted_matrix = np.clip(weighted_matrix, weighted_z_floor, weighted_z_ceiling).astype(np.int8) + merge_df = pd.concat([matrix, pd.Series(weighted_matrix, name="combined")], axis=1) weighted_matrix = pd.DataFrame( { From 0a795e12684c2e8e44dcb93050a22e2e0b0e3bd4 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:28:41 -0600 Subject: [PATCH 140/265] refactor: async create directories --- main/como/combine_distributions.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index 6a251180..59c11917 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -34,6 +34,12 @@ async def _combine_z_distribution_for_batch( weighted_z_floor: int, weighted_z_ceiling: int, ) -> pd.DataFrame: + await asyncio.gather( + *[ + aiofiles.os.makedirs(output_combined_matrix_filepath.parent.as_posix(), exist_ok=True), + aiofiles.os.makedirs(output_figure_dirpath.as_posix(), exist_ok=True), + ] + ) if _num_rows(matrix) < 2: return matrix From fdf415fdb360146509e4526f6b614c6a72e817e6 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:29:06 -0600 Subject: [PATCH 141/265] refactor: move when early return happens --- main/como/combine_distributions.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index 59c11917..4e984dec 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -41,7 +41,17 @@ async def _combine_z_distribution_for_batch( ] ) - if _num_rows(matrix) < 2: + logger.trace( + f"Combining z-score distributions: batch #{batch.batch_num}, " + f"samples: {len(batch.sample_names)}, " + f"source: '{source.value}', " + f"context: '{context_name}'" + ) + if _num_columns(matrix) < 2: + logger.trace( + f"A single sample exists for batch '{batch.batch_num}'. " + f"Returning as-is because no additional combining can be done" + ) return matrix weighted_matrix = np.apply_along_axis( From 8c1ef047d35ccc40bf5d37f069c0341984d84088 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:29:18 -0600 Subject: [PATCH 142/265] fix: remove unused z score calculation --- main/como/combine_distributions.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index 4e984dec..2e763268 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -54,13 +54,6 @@ async def _combine_z_distribution_for_batch( ) return matrix - weighted_matrix = np.apply_along_axis( - weighted_z, - axis=1, - arr=matrix.iloc[:, 1:].values, - floor=weighted_z_floor, - ceiling=weighted_z_ceiling, - ) values = matrix.iloc[:, 1:].values weighted_matrix = np.sum(values, axis=1) / np.sqrt(values.shape[1]) weighted_matrix = np.clip(weighted_matrix, weighted_z_floor, weighted_z_ceiling).astype(np.int8) From 60eb969ec95d8eafdd3409d563b653cb5146d1f3 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:29:29 -0600 Subject: [PATCH 143/265] fix: store gene ids as string --- main/como/combine_distributions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index 2e763268..d0f89d2a 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -61,7 +61,7 @@ async def _combine_z_distribution_for_batch( merge_df = pd.concat([matrix, pd.Series(weighted_matrix, name="combined")], axis=1) weighted_matrix = pd.DataFrame( { - "ensembl_gene_id": matrix["ensembl_gene_id"].astype(str), + "ensembl_gene_id": matrix["ensembl_gene_id"], "combine_z": weighted_matrix, }, ) From 9cf76c2d992569b9072fa0057fdfb1d40e038301 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:29:47 -0600 Subject: [PATCH 144/265] refactor: more efficient pandas melting --- main/como/combine_distributions.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index d0f89d2a..b0a0ef36 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -65,14 +65,13 @@ async def _combine_z_distribution_for_batch( "combine_z": weighted_matrix, }, ) - - stack_df = pd.concat( - [ - pd.DataFrame( - {"ensembl_gene_id": merge_df["ensembl_gene_id"], "zscore": merge_df[col].astype(float), "source": col} - ) - for col in merge_df.columns[1:] - ] + stack_df = pd.melt( + merge_df, + id_vars=["ensembl_gene_id"], + # Get all columns except ensembl_gene_id + value_vars=[col for col in merge_df.columns if col not in GeneIdentifier._member_map_], + var_name="source", + value_name="zscore", ) if len(stack_df["source"].unique()) > 10: stack_df = stack_df[stack_df["source"] == "combined"] From c7d147764708aac385275f00a26e0135b962800e Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:29:57 -0600 Subject: [PATCH 145/265] fix: graph title name --- main/como/combine_distributions.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index b0a0ef36..7a1c2ceb 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -78,8 +78,9 @@ async def _combine_z_distribution_for_batch( graph_zscore_distribution( stack_df, - title=f"Combined Z-score Distribution for {context_name} - batch #{batch_num}", - output_png_filepath=output_png_filepath, + title=f"Combined Z-score Distribution for {context_name} - batch #{batch.batch_num}", + output_filepath=output_figure_dirpath + / f"{context_name}_{source.value}_batch{batch.batch_num}_combined_zscore_distribution.pdf", ) return weighted_matrix From 3e38a0f92aa6f2b1f9a9b1e55ee6636294f0b79b Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:30:17 -0600 Subject: [PATCH 146/265] refactor: add appropriate column names --- main/como/combine_distributions.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index 7a1c2ceb..d46cbfac 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -82,10 +82,12 @@ async def _combine_z_distribution_for_batch( output_filepath=output_figure_dirpath / f"{context_name}_{source.value}_batch{batch.batch_num}_combined_zscore_distribution.pdf", ) + + weighted_matrix.columns = ["ensembl_gene_id", batch.batch_num] + weighted_matrix.to_csv(output_combined_matrix_filepath, index=False) return weighted_matrix - matrix: pd.DataFrame, async def _combine_z_distribution_for_source( context_name: str, batch_num: int, From e323a9ab02b85b8fa4aa52dcc8a60d5ed636446b Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:30:40 -0600 Subject: [PATCH 147/265] refactor: rename parameter names --- main/como/combine_distributions.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index d46cbfac..6345e469 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -89,10 +89,11 @@ async def _combine_z_distribution_for_batch( async def _combine_z_distribution_for_source( + merged_source_data: pd.DataFrame, context_name: str, - batch_num: int, num_replicates: int, - output_png_filepath: Path, + output_combined_matrix_filepath: Path, + output_figure_filepath: Path, weighted_z_floor: int = -6, weighted_z_ceiling: int = 6, ): From b575d40b17e898e0c9e9f920283a9b06067bdeff Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:31:26 -0600 Subject: [PATCH 148/265] refactor: log for early return --- main/como/combine_distributions.py | 35 +++++++++++++++++------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index 6345e469..7c6cb1b1 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -97,21 +97,10 @@ async def _combine_z_distribution_for_source( weighted_z_floor: int = -6, weighted_z_ceiling: int = 6, ): - def weighted_z( - x: npt.NDArray[float], - n_reps: int, - floor: int, - ceiling: int, - ) -> npt.NDArray[float]: - na_values = np.where(np.isnan(x))[0] - if len(na_values) > 0: - x = np.delete(x, na_values) - n_reps = np.delete(n_reps, na_values) - weights = n_reps / np.sum(n_reps) - numerator = np.sum(weights * x) - denominator = np.sqrt(np.sum(weights**2)) - result = numerator / denominator - return np.clip(result, floor, ceiling) + if _num_columns(merged_source_data) <= 2: + logger.warning("A single source exists, returning matrix as-is because no additional combining can be done") + merged_source_data.columns = ["ensembl_gene_id", "combine_z"] + return merged_source_data if _num_rows(matrix) < 2: matrix.columns = ["entrez_gene_id", "combine_z"] @@ -141,6 +130,22 @@ def weighted_z( df=stack_df, title=f"Combined Z-score Distribution for {context_name} - batch #{batch_num}", output_png_filepath=output_png_filepath, + values = merged_source_data.iloc[:, 1:].values + mask = ~np.isnan(values) + masked_values = np.where(mask, values, 0) # Replace NaN with 0 + masked_num_replicates = np.where(mask, num_replicates, 0) + + weights = masked_num_replicates / np.sum(masked_num_replicates, axis=1, keepdims=True) + numerator = np.sum(weights * masked_values, axis=1) + denominator = np.sqrt(np.sum(weights**2, axis=1)) + weighted_matrix = numerator / denominator + weighted_matrix = np.clip(weighted_matrix, weighted_z_floor, weighted_z_ceiling) + merge_df = pd.concat([merged_source_data, pd.Series(weighted_matrix, name="combined")], axis=1) + weighted_matrix = pd.DataFrame( + { + "ensembl_gene_id": merged_source_data["ensembl_gene_id"], + "combine_z": weighted_matrix, + } ) return weighted_matrix From b2d7b2476e42013bb180c999642f4d78401d25de Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:31:43 -0600 Subject: [PATCH 149/265] feat: async create directories --- main/como/combine_distributions.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index 7c6cb1b1..017059c8 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -124,6 +124,12 @@ async def _combine_z_distribution_for_source( {"ensembl_gene_id": merge_df["ensembl_gene_id"], "zscore": merge_df[col].astype(float), "source": col} for col in merge_df.columns[1:] ) + print(f"Making directory for '{output_combined_matrix_filepath.parent}'") + print(f"Making directory for '{output_figure_filepath.parent}'") + await asyncio.gather( + *[ + aiofiles.os.makedirs(output_combined_matrix_filepath.parent.as_posix(), exist_ok=True), + aiofiles.os.makedirs(output_figure_filepath.parent.as_posix(), exist_ok=True), ] ) graph_zscore_distribution( From d847da27d9a67695c9bc6351c87952a95855ed34 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:32:23 -0600 Subject: [PATCH 150/265] style: add logging --- main/como/combine_distributions.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index 017059c8..e6f0fa60 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -136,6 +136,8 @@ async def _combine_z_distribution_for_source( df=stack_df, title=f"Combined Z-score Distribution for {context_name} - batch #{batch_num}", output_png_filepath=output_png_filepath, + + logger.trace(f"Found {_num_columns(merged_source_data) - 1} samples for context '{context_name}' to combine") values = merged_source_data.iloc[:, 1:].values mask = ~np.isnan(values) masked_values = np.where(mask, values, 0) # Replace NaN with 0 @@ -146,6 +148,7 @@ async def _combine_z_distribution_for_source( denominator = np.sqrt(np.sum(weights**2, axis=1)) weighted_matrix = numerator / denominator weighted_matrix = np.clip(weighted_matrix, weighted_z_floor, weighted_z_ceiling) + logger.trace("Finished combining z-distribution") merge_df = pd.concat([merged_source_data, pd.Series(weighted_matrix, name="combined")], axis=1) weighted_matrix = pd.DataFrame( { From 3a47f205638b94b36ff44f3f91cbf55e4703bb22 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:32:41 -0600 Subject: [PATCH 151/265] refactor: remove old z score calculation code --- main/como/combine_distributions.py | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index e6f0fa60..0182af84 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -102,28 +102,6 @@ async def _combine_z_distribution_for_source( merged_source_data.columns = ["ensembl_gene_id", "combine_z"] return merged_source_data - if _num_rows(matrix) < 2: - matrix.columns = ["entrez_gene_id", "combine_z"] - return matrix - - weighted_matrix = np.apply_along_axis( - weighted_z, - axis=1, - arr=matrix.iloc[:, 1:].values, - n_reps=num_replicates, - floor=weighted_z_floor, - ceiling=weighted_z_ceiling, - ) - merge_df = pd.concat([matrix, pd.Series(weighted_matrix, name="combined")], axis=1) - weighted_matrix = pd.DataFrame( - {"ensembl_gene_id": matrix["ensembl_gene_id"].astype(str), "combine_z": weighted_matrix} - ) - stack_df = pd.concat( - [ - pd.DataFrame( - {"ensembl_gene_id": merge_df["ensembl_gene_id"], "zscore": merge_df[col].astype(float), "source": col} - for col in merge_df.columns[1:] - ) print(f"Making directory for '{output_combined_matrix_filepath.parent}'") print(f"Making directory for '{output_figure_filepath.parent}'") await asyncio.gather( @@ -132,10 +110,6 @@ async def _combine_z_distribution_for_source( aiofiles.os.makedirs(output_figure_filepath.parent.as_posix(), exist_ok=True), ] ) - graph_zscore_distribution( - df=stack_df, - title=f"Combined Z-score Distribution for {context_name} - batch #{batch_num}", - output_png_filepath=output_png_filepath, logger.trace(f"Found {_num_columns(merged_source_data) - 1} samples for context '{context_name}' to combine") values = merged_source_data.iloc[:, 1:].values From 229ea7c7089a32a571538f8bf9011e4d9d22ec21 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:32:56 -0600 Subject: [PATCH 152/265] refactor: better function name --- main/como/combine_distributions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index 0182af84..1e19e70f 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -133,10 +133,10 @@ async def _combine_z_distribution_for_source( return weighted_matrix -def _combine_omics_zdistros( +def _combine_z_distribution_for_context( context: str, zscore_results: list[_CombineOmicsInput], - output_png_filepath: Path, + output_graph_filepath: Path, weighted_z_floor: int = -6, weighted_z_ceiling: int = 6, ): From 77c9ff1132f520fd7806e7bc4d23d41e7d72e748 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:33:49 -0600 Subject: [PATCH 153/265] refactor: pythonic z score calculation --- main/como/combine_distributions.py | 54 ++++++++++++------------------ 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index 1e19e70f..12de7119 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -140,47 +140,37 @@ def _combine_z_distribution_for_context( weighted_z_floor: int = -6, weighted_z_ceiling: int = 6, ): - def weighted_z( - x: npt.NDArray[float], - weights, - floor: int, - ceiling: int, - ): - na_values = np.where(np.isnan(x))[0] - if len(na_values) > 0: - x = np.delete(x, na_values) - weights = np.delete(weights, na_values) - weights = weights / np.sum(weights) - numerator = np.sum(weights * x) - denominator = np.sqrt(np.sum(weights**2)) - result = numerator / denominator - return np.clip(result, floor, ceiling) - z_matrix = pd.DataFrame() - for result in zscore_results: - result.z_score_matrix.columns = ["ensembl_gene_id", result.type] - z_matrix = ( - result.z_score_matrix - if z_matrix.empty - else pd.merge(z_matrix, result.z_score_matrix, on="ensembl_gene_id", how="outer") + z_matrices = [ + res.z_score_matrix.set_index("ensembl_gene_id").rename( + columns={col: res.type.value for col in res.z_score_matrix.columns[1:]} ) - - combined_z_matrix = ( - np.apply_along_axis( - weighted_z, - axis=1, - arr=z_matrix.iloc[:, 1:].values, - weights=[r.weight for r in zscore_results], - floor=weighted_z_floor, - ceiling=weighted_z_ceiling, + for res in zscore_results + ] + z_matrix = pd.concat(z_matrices, axis=1, join="outer").reset_index() + if _num_columns(z_matrix) <= 1: + logger.trace( + f"Only 1 source exists for '{context}', returning dataframe as-is becuase no data exists to combine" ) if _num_rows(z_matrix) > 2 else z_matrix.iloc[:, 1:].values ).ravel() merge_df = pd.concat([z_matrix, pd.Series(combined_z_matrix, name="combined")], axis=1) combined_z_matrix = pd.DataFrame( + values = z_matrix.iloc[:, 1:].values + weights = np.array([r.weight for r in zscore_results]) + mask = ~np.isnan(values) + masked_values = np.where(mask, values, 0) + masked_weights = np.where(mask, weights, 0) + + normalized_weights = masked_weights / np.sum(masked_weights, axis=1, keepdims=True) + numerator = np.sum(normalized_weights * masked_values, axis=1) + denominator = np.sqrt(np.sum(normalized_weights**2, axis=1)) + combined_z_matrix = numerator / denominator + combined_z_matrix = np.clip(combined_z_matrix, weighted_z_floor, weighted_z_ceiling) + combined_z_matrix_df = pd.DataFrame( { - "ensembl_gene_id": z_matrix["ensembl_gene_id"].astype(str), + "ensembl_gene_id": z_matrix["ensembl_gene_id"], "combine_z": combined_z_matrix, } ) From 3df7503c3311e4e39aa3e786dd668105b61af38d Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:33:56 -0600 Subject: [PATCH 154/265] style: log for early return --- main/como/combine_distributions.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index 12de7119..88094c7a 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -140,6 +140,9 @@ def _combine_z_distribution_for_context( weighted_z_floor: int = -6, weighted_z_ceiling: int = 6, ): + if not zscore_results: + logger.warning("No zscore results exist, returning empty dataframe") + return pd.DataFrame({"ensembl_gene_id": [], "combine_z": []}) z_matrices = [ res.z_score_matrix.set_index("ensembl_gene_id").rename( From 7a4140124d80b6ea89342836288ac99608cbd62a Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:34:38 -0600 Subject: [PATCH 155/265] refactor: remove old z score calculation code --- main/como/combine_distributions.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index 88094c7a..5b1010d4 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -155,11 +155,9 @@ def _combine_z_distribution_for_context( logger.trace( f"Only 1 source exists for '{context}', returning dataframe as-is becuase no data exists to combine" ) - if _num_rows(z_matrix) > 2 - else z_matrix.iloc[:, 1:].values - ).ravel() - merge_df = pd.concat([z_matrix, pd.Series(combined_z_matrix, name="combined")], axis=1) - combined_z_matrix = pd.DataFrame( + z_matrix.columns = ["ensembl_gene_id", "combine_z"] + return z_matrix + values = z_matrix.iloc[:, 1:].values weights = np.array([r.weight for r in zscore_results]) mask = ~np.isnan(values) From fc7b95b65a2894b5e8c966d3682f536f1e9fa6d4 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:39:08 -0600 Subject: [PATCH 156/265] refactor: more efficient pandas melting --- main/como/combine_distributions.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index 5b1010d4..12b94924 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -130,6 +130,14 @@ async def _combine_z_distribution_for_source( "combine_z": weighted_matrix, } ) + + stack_df = pd.melt( + merge_df, + id_vars=["ensembl_gene_id"], + value_vars=merge_df.columns[1:], # all other columns are values + var_name="source", + value_name="zscore", + ) return weighted_matrix From 78a1ab6b5c746cdf389e4bbc1be4d1fa8032cd2c Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:40:14 -0600 Subject: [PATCH 157/265] refactor: temporarily remove z score graphing --- main/como/combine_distributions.py | 55 ++++++++++++++++-------------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index 12b94924..63218fca 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -76,12 +76,12 @@ async def _combine_z_distribution_for_batch( if len(stack_df["source"].unique()) > 10: stack_df = stack_df[stack_df["source"] == "combined"] - graph_zscore_distribution( - stack_df, - title=f"Combined Z-score Distribution for {context_name} - batch #{batch.batch_num}", - output_filepath=output_figure_dirpath - / f"{context_name}_{source.value}_batch{batch.batch_num}_combined_zscore_distribution.pdf", - ) + # graph_zscore_distribution( + # stack_df, + # title=f"Combined Z-score Distribution for {context_name} - batch #{batch.batch_num}", + # output_filepath=output_figure_dirpath + # / f"{context_name}_{source.value}_batch{batch.batch_num}_combined_zscore_distribution.pdf", + # ) weighted_matrix.columns = ["ensembl_gene_id", batch.batch_num] weighted_matrix.to_csv(output_combined_matrix_filepath, index=False) @@ -102,8 +102,6 @@ async def _combine_z_distribution_for_source( merged_source_data.columns = ["ensembl_gene_id", "combine_z"] return merged_source_data - print(f"Making directory for '{output_combined_matrix_filepath.parent}'") - print(f"Making directory for '{output_figure_filepath.parent}'") await asyncio.gather( *[ aiofiles.os.makedirs(output_combined_matrix_filepath.parent.as_posix(), exist_ok=True), @@ -138,6 +136,11 @@ async def _combine_z_distribution_for_source( var_name="source", value_name="zscore", ) + # graph_zscore_distribution( + # df=stack_df, + # title=f"Combined Z-score Distribution for {context_name}", + # output_filepath=output_figure_filepath, + # ) return weighted_matrix @@ -184,25 +187,27 @@ def _combine_z_distribution_for_context( } ) - stack_df = pd.concat( - [ - pd.DataFrame( - { - "ensembl_gene_id": merge_df["ensembl_gene_id"], - "zscore": merge_df[col].astype(float), - "source": col, - } - ) - for col in merge_df.columns[1:] - ] + stack_df = pd.melt( + z_matrix, + id_vars=["ensembl_gene_id"], + value_vars=z_matrix.columns[1:], + var_name="source", + value_name="zscore", ) - - graph_zscore_distribution( - df=stack_df, - title=f"Combined Omics Z-score Distribution for {context}", - output_png_filepath=output_png_filepath, + combined_df = pd.DataFrame( + { + "ensembl_gene_id": z_matrix["ensembl_gene_id"], + "zscore": combined_z_matrix, + "source": "combined", + } ) - return combined_z_matrix + stack_df = pd.concat([stack_df, combined_df]) + # graph_zscore_distribution( + # df=stack_df, + # title=f"Combined Z-score Distribution for {context}", + # output_filepath=output_graph_filepath, + # ) + return combined_z_matrix_df async def _begin_combining_distributions( From f34b1db9fbe1c4fd14e3114a2a82c3540c77e484 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:40:42 -0600 Subject: [PATCH 158/265] refactor: use new function names --- main/como/combine_distributions.py | 39 +++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index 63218fca..0096336d 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -257,12 +257,39 @@ async def _begin_combining_distributions( merged_batch_results = ( df if merged_batch_results.empty else merged_batch_results.merge(df, on="ensembl_gene_id", how="outer") ) - zscore_results.append(_CombineOmicsInput(z_score_matrix=combine_batches_zscore, type=source, weight=weight)) # type: ignore - combine_batches_zscore.to_csv(output_filepath, index=False) - combined_z_omics = _combine_omics_zdistros( + merged_source_results: pd.DataFrame = await _combine_z_distribution_for_source( + merged_source_data=merged_batch_results, + context_name=context_name, + num_replicates=sum(batch.num_samples for batch in batch_names[source.value]), + output_combined_matrix_filepath=( + output_filepaths[source.value].parent + / f"{context_name}_{source.value}_combined_zscore_distribution.csv" + ), + output_figure_filepath=( + output_figure_dirpath / f"{context_name}_{source.value}_combined_zscore_distribution.pdf" + ), + weighted_z_floor=weighted_z_floor, + weighted_z_ceiling=weighted_z_ceiling, + ) + z_score_results.append( + _CombineOmicsInput( + z_score_matrix=merged_source_results, + type=source, + weight=source_weights[source.value], + ) + ) + merged_source_results.to_csv(output_filepaths[source.value]) + logger.success( + f"Wrote z-scores for source '{source.value}' " + f"in context '{context_name}' to '{output_filepaths[source.value]}'" + ) + + logger.trace(f"Combining z-score distributions for all sources in context '{context_name}'") + merged_context_results = _combine_z_distribution_for_context( context=context_name, - zscore_results=zscore_results, - output_png_filepath=output_figure_dirpath / f"{context_name}_combined_omics_distribution.png", + zscore_results=z_score_results, + output_graph_filepath=output_figure_dirpath / f"{context_name}_combined_omics_distribution.pdf", ) - combined_z_omics.to_csv(output_final_model_scores, index=False) + merged_context_results.to_csv(output_final_model_scores, index=False) + logger.success(f"Finished combining z-scores for context '{context_name}'") From 71ee8ccbe7af3ba95934ee55add99b566e42fcad Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:41:19 -0600 Subject: [PATCH 159/265] refactor: use matplotlib for plot creation --- main/como/graph/__init__.py | 47 ++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/main/como/graph/__init__.py b/main/como/graph/__init__.py index 1bb4cdb8..1f6c6a22 100644 --- a/main/como/graph/__init__.py +++ b/main/como/graph/__init__.py @@ -1,7 +1,9 @@ from pathlib import Path from loguru import logger import pandas as pd -import plotly.express as px +from matplotlib import pyplot as plt +import seaborn as sns + __all__ = ["z_score_distribution"] @@ -9,27 +11,34 @@ def z_score_distribution( df: pd.DataFrame, title: str, - output_png_filepath: Path, + output_filepath: Path, ): - if not output_png_filepath.suffix == ".png": + if output_filepath.suffix not in {".png", ".pdf", ".svg"}: logger.warning( - f"Expected .png suffix for output_png_filepath, got {output_png_filepath.suffix}. Defaulting to .png" + f"Expected .png, .pdf, or .svg suffix for output_png_filepath, got {output_filepath.suffix}. Defaulting to .pdf" ) - output_png_filepath = output_png_filepath.with_suffix(".png") - - fig = px.histogram( - df, - x="zscore", - color="source", - nbins=100, - marginal="rug", - title=title, - ) + output_filepath = output_filepath.with_suffix(".pdf") + logger.trace(f"Graphing z-score distribution") + output_filepath.parent.mkdir(parents=True, exist_ok=True) + output_filepath.unlink(missing_ok=True) - fig.update_layout(xaxis_title="Z-score", yaxis_title="Frequency", font={"family": "sans-serif", "size": 12}) + plt.figure(figsize=(10, 6)) - # Simplified plot for many sources (optional) - if len(df["source"].unique()) > 10: - fig.update_layout(showlegend=False) + if len(df["source"].unique()) == 1: + ax = sns.histplot(df, x="zscore", bins=100, kde=True) + sns.rugplot(df, x="zscore", ax=ax) + else: + sns.histplot(df, x="zscore", hue="source", bins=100, kde=True, element="step") + plt.legend(loc="upper right", frameon=False, title=None) - fig.write_image(output_png_filepath) + plt.title(title) + plt.xlabel("Z-score") + plt.ylabel("Frequency") + plt.xticks(fontsize=12) + plt.yticks(fontsize=12) + plt.gca().spines["top"].set_visible(False) + plt.gca().spines["right"].set_visible(False) + plt.tight_layout() + plt.savefig(output_filepath) + plt.close() + logger.success(f"Saved z-score distribution graph to '{output_filepath}'") From b6cf039c92958ff54c620800373c73cb1dcb566c Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:42:48 -0600 Subject: [PATCH 160/265] refactor: exchange plotly for seaborn --- pyproject.toml | 2 +- uv.lock | 26 ++------------------------ 2 files changed, 3 insertions(+), 25 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 70ceb3e8..c6921422 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,10 +17,10 @@ dependencies = [ "numpy<2.0", "openpyxl>=3.1.5", "pandas>=1.3.5", - "plotly>=5.24.1", "scanpy>=1.10.4", "scikit-learn>=1.5.2", "scipy>=1.7.3", + "seaborn>=0.13.2", "setuptools<60.0", "troppo@git+https://github.com/JoshLoecker/troppo@master", ] diff --git a/uv.lock b/uv.lock index 7d354a68..81292416 100644 --- a/uv.lock +++ b/uv.lock @@ -437,10 +437,10 @@ dependencies = [ { name = "numpy" }, { name = "openpyxl" }, { name = "pandas" }, - { name = "plotly" }, { name = "scanpy" }, { name = "scikit-learn" }, { name = "scipy" }, + { name = "seaborn" }, { name = "setuptools" }, { name = "troppo" }, ] @@ -481,7 +481,6 @@ requires-dist = [ { name = "numpy", specifier = "<2.0" }, { name = "openpyxl", specifier = ">=3.1.5" }, { name = "pandas", specifier = ">=1.3.5" }, - { name = "plotly", specifier = ">=5.24.1" }, { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.3.3" }, { name = "pytest-asyncio", marker = "extra == 'dev'", specifier = ">=0.24.0" }, { name = "pytest-cov", marker = "extra == 'dev'", specifier = ">=6.0.0" }, @@ -489,6 +488,7 @@ requires-dist = [ { name = "scanpy", specifier = ">=1.10.4" }, { name = "scikit-learn", specifier = ">=1.5.2" }, { name = "scipy", specifier = ">=1.7.3" }, + { name = "seaborn", specifier = ">=0.13.2" }, { name = "setuptools", specifier = "<60.0" }, { name = "troppo", git = "https://github.com/JoshLoecker/troppo?rev=master" }, ] @@ -1825,19 +1825,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb", size = 18439 }, ] -[[package]] -name = "plotly" -version = "5.24.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "packaging" }, - { name = "tenacity" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/79/4f/428f6d959818d7425a94c190a6b26fbc58035cbef40bf249be0b62a9aedd/plotly-5.24.1.tar.gz", hash = "sha256:dbc8ac8339d248a4bcc36e08a5659bacfe1b079390b8953533f4eb22169b4bae", size = 9479398 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/ae/580600f441f6fc05218bd6c9d5794f4aef072a7d9093b291f1c50a9db8bc/plotly-5.24.1-py3-none-any.whl", hash = "sha256:f67073a1e637eb0dc3e46324d9d51e2fe76e9727c892dde64ddf1e1b51f29089", size = 19054220 }, -] - [[package]] name = "pluggy" version = "1.5.0" @@ -2724,15 +2711,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/99/ff/c87e0622b1dadea79d2fb0b25ade9ed98954c9033722eb707053d310d4f3/sympy-1.13.3-py3-none-any.whl", hash = "sha256:54612cf55a62755ee71824ce692986f23c88ffa77207b30c1368eda4a7060f73", size = 6189483 }, ] -[[package]] -name = "tenacity" -version = "9.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cd/94/91fccdb4b8110642462e653d5dcb27e7b674742ad68efd146367da7bdb10/tenacity-9.0.0.tar.gz", hash = "sha256:807f37ca97d62aa361264d497b0e31e92b8027044942bfa756160d908320d73b", size = 47421 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b6/cb/b86984bed139586d01532a587464b5805f12e397594f19f931c4c2fbfa61/tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539", size = 28169 }, -] - [[package]] name = "termcolor" version = "2.5.0" From 4c424b5e19ece98dff1a1a05b2c34b9fde8aae98 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:43:18 -0600 Subject: [PATCH 161/265] feat: validate that source types process in order --- tests/unit/test_data_types.py | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 tests/unit/test_data_types.py diff --git a/tests/unit/test_data_types.py b/tests/unit/test_data_types.py new file mode 100644 index 00000000..9688ddff --- /dev/null +++ b/tests/unit/test_data_types.py @@ -0,0 +1,10 @@ +from como.data_types import SourceTypes + + +def test_source_types(): + """Validate that source types always go in the order of 'trna', 'mrna', 'scrna', 'protemics'.""" + expected_order = ["trna", "mrna", "scrna", "proteomics"] + for expected, source in zip(expected_order, SourceTypes): + expected: str + source: SourceTypes + assert expected == source.value From 22b82eff2b6bd95983ec9656a0f728bd73a3dbfd Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 15:48:29 -0600 Subject: [PATCH 162/265] refactor: add logging, use _log_and_raise_error --- main/como/proteomics/FTPManager.py | 36 +++++++++++++++---- main/como/proteomics/proteomics_preprocess.py | 14 +++++--- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/main/como/proteomics/FTPManager.py b/main/como/proteomics/FTPManager.py index 1be45d91..d2807cc8 100644 --- a/main/como/proteomics/FTPManager.py +++ b/main/como/proteomics/FTPManager.py @@ -14,8 +14,11 @@ from urllib.parse import urlparse import aioftp +from loguru import logger -from .FileInformation import FileInformation, clear_print +from como.proteomics.FileInformation import FileInformation, clear_print +from como.utils import _log_and_raise_error +from como.data_types import LogLevel async def aioftp_client( @@ -42,8 +45,11 @@ async def aioftp_client( attempt_num += 1 time.sleep(5) if not connection_successful: - print() - raise ConnectionResetError("Could not connect to FTP server") + _log_and_raise_error( + "Could not connect to FTP server", + error=ConnectionResetError, + level=LogLevel.ERROR, + ) return client @@ -93,11 +99,19 @@ async def _get_info(self) -> None: if url_parse.hostname is not None: host = url_parse.hostname else: - raise ValueError(f"Unable to identify hostname from url: {self._root_link}") + _log_and_raise_error( + f"Unable to identify hostname from url: {self._root_link}", + error=ValueError, + level=LogLevel.ERROR, + ) if url_parse.path != "": folder = url_parse.path else: - raise ValueError(f"Unable to identify folder or path from url: {self._root_link}") + _log_and_raise_error( + f"Unable to identify folder or path from url: {self._root_link}", + error=ValueError, + level=LogLevel.ERROR, + ) client = await aioftp_client(host=host) for path, info in await client.list(folder, recursive=True): @@ -172,11 +186,19 @@ async def _aioftp_download_data(self, file_information: FileInformation, semapho if url_parse.hostname is not None: host = url_parse.hostname else: - raise ValueError(f"Unable to identify hostname from url: {file_information.download_url}") + _log_and_raise_error( + f"Unable to identify hostname from url: {file_information.download_url}", + error=ValueError, + level=LogLevel.ERROR, + ) if url_parse.path != "": folder = url_parse.path else: - raise ValueError(f"Unable to identify folder or path from url: {file_information.download_url}") + _log_and_raise_error( + f"Unable to identify folder or path from url: {file_information.download_url}", + error=ValueError, + level=LogLevel.ERROR, + ) # Convert file size from byte to MB size_mb: int = round(file_information.file_size / (1024**2)) diff --git a/main/como/proteomics/proteomics_preprocess.py b/main/como/proteomics/proteomics_preprocess.py index 89264ca2..7a7df11d 100644 --- a/main/como/proteomics/proteomics_preprocess.py +++ b/main/como/proteomics/proteomics_preprocess.py @@ -7,8 +7,9 @@ from loguru import logger -from . import Crux, FTPManager -from .FileInformation import FileInformation +from como.data_types import LogLevel +from como.proteomics import Crux, FileInformation, FTPManager +from como.utils import _log_and_raise_error class ArgParseFormatter(argparse.RawTextHelpFormatter, argparse.ArgumentDefaultsHelpFormatter): @@ -308,14 +309,17 @@ def parse_args() -> argparse.Namespace: # Validte the input file exists if not Path(args.input_csv).is_file(): - raise FileNotFoundError(f"Input file {args.input} does not exist!") + _log_and_raise_error(f"Input file {args.input} does not exist!", error=FileNotFoundError, level=LogLevel.ERROR) if args.core_count == "all": args.core_count = os.cpu_count() elif not str(args.core_count).isdigit(): - raise ValueError( - f"Invalid option '{args.core_count}' for option '--cores'. Enter an integer or 'all' to use all cores" + _log_and_raise_error( + f"Invalid option '{args.core_count}' for option '--cores'. Enter an integer or 'all' to use all cores", + error=ValueError, + level=LogLevel.ERROR, ) + else: args.core_count = int(args.core_count) if args.core_count > os.cpu_count(): From 82ce6b3ea25031c738d485a87c61e3e86a8920f2 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 16:13:51 -0600 Subject: [PATCH 163/265] refactor: remove plotly graphing --- main/como/rnaseq_gen.py | 78 +++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 41 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 8fe2780a..6a570c26 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -11,17 +11,16 @@ from pathlib import Path from typing import Callable, NamedTuple +import matplotlib.pyplot as plt import numpy as np import numpy.typing as npt import pandas as pd -import plotly.graph_objs as go -import scanpy as sc +import seaborn as sns import sklearn import sklearn.neighbors from fast_bioservices.pipeline import ensembl_to_gene_id_and_symbol, gene_symbol_to_ensembl_and_gene_id from loguru import logger from pandas import DataFrame -from plotly.subplots import make_subplots from scipy.signal import find_peaks from sklearn.neighbors import KernelDensity @@ -412,10 +411,11 @@ def zfpkm_transform( return results, zfpkm_df -def zfpkm_plot(results, *, plot_xfloor: int = -4, subplot_titles: bool = True): +def zfpkm_plot(results, *, output_png_filepath: Path, plot_xfloor: int = -4, subplot_titles: bool = True): """Plot the log2(FPKM) density and fitted Gaussian for each sample. :param results: A dictionary of intermediate results from zfpkm_transform. + :param output_png_filepath: Output filepath location :param: subplot_titles: Whether to display facet titles (sample names). :param plot_xfloor: Lower limit for the x-axis. :param subplot_titles: Whether to display facet titles (sample names). @@ -445,45 +445,30 @@ def zfpkm_plot(results, *, plot_xfloor: int = -4, subplot_titles: bool = True): mega_df.columns = pd.Series(data=["sample_name", "log2fpkm", "fpkm_density", "fitted_density_scaled"]) mega_df = mega_df.melt(id_vars=["log2fpkm", "sample_name"], var_name="source", value_name="density") - subplot_titles = list(results.keys()) if subplot_titles else None - fig = make_subplots( - rows=len(results), - cols=1, - subplot_titles=subplot_titles, - vertical_spacing=min(0.05, (1 / (len(results) - 1))), - ) + fig, axes = plt.subplot(len(results), 1, figsize=(8, 4 * len(results))) + if len(results) == 1: + axes = [axes] for i, sample_name in enumerate(results, start=1): sample_data = mega_df[mega_df["sample_name"] == sample_name] - traces = [] + axis = axes[i] + for source_type in sample_data["source"].unique(): group = sample_data[sample_data["source"] == source_type] - traces.append( - go.Scatter( - x=group["log2fpkm"], - y=group["density"], - mode="lines", - name=source_type, - legendgroup=source_type, - ) - ) - fig.add_traces(traces, rows=i, cols=1) - fig.update_xaxes(title_text="log2(FPKM)", range=[plot_xfloor, sample_data["log2fpkm"].max()], row=i, col=1) - fig.update_yaxes(title_text="density [scaled]", row=i, col=1) - fig.update_layout(legend_tracegroupgap=0) + sns.lineplot(data=group, x="log2fpkm", y="density", label=source_type, ax=axis) - # for i, (name, group) in enumerate(mega_df.groupby("sample_name"), start=1): - # fig.add_trace( - # trace=go.Scatter(x=group["log2fpkm"], y=group["density"], mode="lines", name=name, legendgroup=name), - # row=i, - # col=1, - # ) - # fig.update_xaxes(title_text="log2(FPKM)", range=[plot_xfloor, max(group["log2fpkm"].tolist())], row=i, col=1) - # fig.update_yaxes(title_text="density [scaled]", row=i, col=1) - # fig.update_layout(legend_tracegroupgap=0) + axis.set_xlim(plot_xfloor, sample_data["log2fpkm"].max()) + axis.set_xlabel("log2(FPKM)") + axis.set_ylabel("density [scaled]") + axis.legend(title="Source") - fig.update_layout(height=600 * len(results), width=1000, title_text="zFPKM Plots", showlegend=True) - fig.write_image("zfpkm_plot.png") + plt.tight_layout() + if output_png_filepath.suffix != ".png": + logger.warning( + f"Output filepath did not end in '.png', setting to '.png' now. Got: '{output_png_filepath.suffix}'" + ) + output_png_filepath = output_png_filepath.with_suffix(".png") + plt.savefig(output_png_filepath) def calculate_z_score(metrics: NamedMetrics) -> NamedMetrics: @@ -602,6 +587,7 @@ def zfpkm_filter( force_zfpkm_plot: bool, peak_parameters: PeakIdentificationParameters, bandwidth: int, + output_png_filepath: Path | None, ) -> NamedMetrics: """Apply zFPKM filtering to the FPKM matrix for a given sample.""" min_sample_expression = filtering_options.replicate_ratio @@ -625,7 +611,9 @@ def zfpkm_filter( "If you would like to plot them anyway, set 'force_zfpkm_plot' to True" ) else: - zfpkm_plot(results) + if output_png_filepath is None: + _log_and_raise_error("Output zFPKM PNG filepath is None.", error=ValueError, level=LogLevel.ERROR) + zfpkm_plot(results, output_png_filepath=output_png_filepath) # determine which genes are expressed min_samples = round(min_sample_expression * len(zfpkm_df.columns)) @@ -652,6 +640,7 @@ def filter_counts( force_zfpkm_plot: bool, peak_parameters: PeakIdentificationParameters, bandwidth: int, + output_png_filepath: Path | None = None, ) -> NamedMetrics: """Filter the count matrix based on the specified technique.""" match technique: @@ -669,6 +658,7 @@ def filter_counts( force_zfpkm_plot=force_zfpkm_plot, peak_parameters=peak_parameters, bandwidth=bandwidth, + output_png_filepath=output_png_filepath, ) case FilteringTechnique.UMI: # UMI filtering is the same as zFPKM filtering without calculating FPKM @@ -679,6 +669,7 @@ def filter_counts( force_zfpkm_plot=force_zfpkm_plot, peak_parameters=peak_parameters, bandwidth=bandwidth, + output_png_filepath=output_png_filepath, ) case _: _log_and_raise_error( @@ -702,10 +693,11 @@ async def _process( technique: FilteringTechnique, cut_off: int | float, force_zfpkm_plot: bool, - output_boolean_activity_filepath: Path, - output_zscore_normalization_filepath: Path, peak_parameters: PeakIdentificationParameters, bandwidth: int, + output_boolean_activity_filepath: Path, + output_zscore_normalization_filepath: Path, + output_zfpkm_png_filepath: Path | None, ): """Save the results of the RNA-Seq tests to a CSV file.""" output_boolean_activity_filepath.parent.mkdir(parents=True, exist_ok=True) @@ -745,6 +737,7 @@ async def _process( force_zfpkm_plot=force_zfpkm_plot, peak_parameters=peak_parameters, bandwidth=bandwidth, + output_png_filepath=output_zfpkm_png_filepath, ) merged_zscore_df = pd.DataFrame() @@ -827,6 +820,7 @@ async def rnaseq_gen( force_zfpkm_plot: bool = False, log_level: LogLevel = LogLevel.INFO, log_location: str | TextIOWrapper = sys.stderr, + output_zfpkm_png_filepath: Path | None = None, ) -> None: """Generate a list of active and high-confidence genes from a gene count matrix. @@ -857,6 +851,7 @@ async def rnaseq_gen( :param force_zfpkm_plot: If too many samples exist, should plotting be done anyway? :param log_level: The level of logging to output :param log_location: The location to write logs to + :param output_zfpkm_png_filepath: Optional filepath to save zFPKM plots :return: None """ _set_up_logging(level=log_level, location=log_location) @@ -948,8 +943,9 @@ async def rnaseq_gen( technique=technique, cut_off=cutoff, force_zfpkm_plot=force_zfpkm_plot, - output_boolean_activity_filepath=output_boolean_activity_filepath, - output_zscore_normalization_filepath=output_zscore_normalization_filepath, peak_parameters=PeakIdentificationParameters(height=zfpkm_peak_height, distance=zfpkm_peak_distance), bandwidth=zfpkm_bandwidth, + output_boolean_activity_filepath=output_boolean_activity_filepath, + output_zscore_normalization_filepath=output_zscore_normalization_filepath, + output_zfpkm_png_filepath=output_zfpkm_png_filepath, ) From b846efdd38e77a9791f7c3f428571afbbca84aeb Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 16:16:35 -0600 Subject: [PATCH 164/265] feat: do not throw error if missing png path --- main/como/rnaseq_gen.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 6a570c26..2bb3a93b 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -411,7 +411,7 @@ def zfpkm_transform( return results, zfpkm_df -def zfpkm_plot(results, *, output_png_filepath: Path, plot_xfloor: int = -4, subplot_titles: bool = True): +def zfpkm_plot(results, *, output_png_filepath: Path, plot_xfloor: int = -4): """Plot the log2(FPKM) density and fitted Gaussian for each sample. :param results: A dictionary of intermediate results from zfpkm_transform. @@ -612,8 +612,11 @@ def zfpkm_filter( ) else: if output_png_filepath is None: - _log_and_raise_error("Output zFPKM PNG filepath is None.", error=ValueError, level=LogLevel.ERROR) - zfpkm_plot(results, output_png_filepath=output_png_filepath) + logger.critical("Output zFPKM PNG filepath is None, set a path to plot zFPKM graphs") + else: + output_png_filepath.parent.mkdir(parents=True, exist_ok=True) + output_png_filepath.unlink(missing_ok=True) + zfpkm_plot(results, output_png_filepath=output_png_filepath) # determine which genes are expressed min_samples = round(min_sample_expression * len(zfpkm_df.columns)) From a43485fde22650f18b7f5c94350536de93be7ad1 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 16:29:26 -0600 Subject: [PATCH 165/265] refactor: move NamedTuple to data_types Signed-off-by: Josh Loecker --- main/como/create_context_specific_model.py | 22 ++-------------------- main/como/data_types.py | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 3d123c40..3d2b759c 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -6,7 +6,6 @@ from collections.abc import Sequence from io import TextIOWrapper from pathlib import Path -from typing import NamedTuple import cobra import numpy as np @@ -20,26 +19,10 @@ from troppo.methods.reconstruction.imat import IMAT, IMATProperties from troppo.methods.reconstruction.tINIT import tINIT, tINITProperties -from como.data_types import Algorithm, CobraCompartments, LogLevel, Solver +from como.data_types import Algorithm, CobraCompartments, LogLevel, Solver, _BoundaryReactions, _BuildResults from como.utils import _log_and_raise_error, _read_file, _set_up_logging, split_gene_expression_data -class _BoundaryReactions(NamedTuple): - """Boundary reactions to be used in the context specific model.""" - - reactions: list[str] - lower_bounds: list[float] - upper_bounds: list[float] - - -class _BuildResults(NamedTuple): - """Results of building a context specific model.""" - - model: cobra.Model - expression_index_list: list[int] - infeasible_reactions: pd.DataFrame - - def _correct_bracket(rule: str, name: str) -> str: """Correct GPR rules to format readable by.""" rule_match = re.search(r"or|and", rule) @@ -492,12 +475,11 @@ async def _build_model( # noqa: C901 pd.DataFrame({"infeasible_reactions": inconsistent_reactions}), pd.DataFrame({"expressed_infeasible_reactions": infeasible_expression_reactions}), pd.DataFrame({"infeasible_force_reactions": infeasible_force_reactions}), - pd.DataFrame({"infeasible_context_reactions": []}), + pd.DataFrame({"infeasible_context_reactions": []}), # Included to maintain legacy support ], ignore_index=True, axis=0, ) - print(inconsistent_and_infeasible_reactions) return _BuildResults( model=context_model_cobra, diff --git a/main/como/data_types.py b/main/como/data_types.py index e4e7d8b2..819f35ba 100644 --- a/main/como/data_types.py +++ b/main/como/data_types.py @@ -6,6 +6,7 @@ from pathlib import Path from typing import ClassVar, NamedTuple +import cobra import pandas as pd from loguru import logger @@ -153,6 +154,22 @@ def get_longhand(cls, shorthand: str) -> str | None: return longhand[0] if longhand else None +class _BuildResults(NamedTuple): + """Results of building a context specific model.""" + + model: cobra.Model + expression_index_list: list[int] + infeasible_reactions: pd.DataFrame + + +class _BoundaryReactions(NamedTuple): + """Boundary reactions to be used in the context specific model.""" + + reactions: list[str] + lower_bounds: list[float] + upper_bounds: list[float] + + @dataclass class _BatchEntry: batch_num: int From 0264c3c4c38b3f48f4f6957a73263cc4d71ecab0 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 16:31:21 -0600 Subject: [PATCH 166/265] fix: comment unused variables Signed-off-by: Josh Loecker --- main/como/combine_distributions.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index 0096336d..f7bd19d3 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -121,7 +121,7 @@ async def _combine_z_distribution_for_source( weighted_matrix = numerator / denominator weighted_matrix = np.clip(weighted_matrix, weighted_z_floor, weighted_z_ceiling) logger.trace("Finished combining z-distribution") - merge_df = pd.concat([merged_source_data, pd.Series(weighted_matrix, name="combined")], axis=1) + # merge_df = pd.concat([merged_source_data, pd.Series(weighted_matrix, name="combined")], axis=1) weighted_matrix = pd.DataFrame( { "ensembl_gene_id": merged_source_data["ensembl_gene_id"], @@ -129,13 +129,13 @@ async def _combine_z_distribution_for_source( } ) - stack_df = pd.melt( - merge_df, - id_vars=["ensembl_gene_id"], - value_vars=merge_df.columns[1:], # all other columns are values - var_name="source", - value_name="zscore", - ) + # stack_df = pd.melt( + # merge_df, + # id_vars=["ensembl_gene_id"], + # value_vars=merge_df.columns[1:], # all other columns are values + # var_name="source", + # value_name="zscore", + # ) # graph_zscore_distribution( # df=stack_df, # title=f"Combined Z-score Distribution for {context_name}", From be4e89e22babe8362baa14e9e797335fd557dff0 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 16:32:03 -0600 Subject: [PATCH 167/265] fix: comment unused variables Signed-off-by: Josh Loecker --- main/como/create_context_specific_model.py | 2 +- main/como/rnaseq_gen.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 3d2b759c..754cfc9a 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -313,7 +313,7 @@ async def _map_expression_to_reaction( error_count += 1 logger.debug(f"Mapped gene expression to reactions, found {error_count} error(s).") - expr_vector = np.array(list(reaction_expression.values()), dtype=float) + # expr_vector = np.array(list(reaction_expression.values()), dtype=float) return reaction_expression diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 2bb3a93b..13181f30 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -802,7 +802,7 @@ async def _process( logger.success(f"Wrote boolean matrix to {output_boolean_activity_filepath}") -async def rnaseq_gen( +async def rnaseq_gen( # noqa: C901 context_name: str, input_rnaseq_filepath: Path, input_gene_info_filepath: Path, From ab96976ef2bb8f125f4f21175a638187d2ae6940 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 16:32:36 -0600 Subject: [PATCH 168/265] fix: line too long Signed-off-by: Josh Loecker --- main/como/rnaseq_preprocess.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index 0846d6d2..013d7f49 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -357,7 +357,8 @@ async def _create_config_df( # noqa: C901 _log_and_raise_error( ( f"\n\nFilename of '{gene_count_filename}' is not valid. " - f"Should be 'contextName_SXRYrZ.tab', where X is the study/batch number, Y is the replicate number, " + f"Should be 'contextName_SXRYrZ.tab', " + f"where X is the study/batch number, Y is the replicate number, " f"and Z is the run number." "\n\nIf not a multi-run sample, exclude 'rZ' from the filename." ), From 8a0f4c6cfb211e6526119cfacda2ad8bd53e3e5c Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 16:43:42 -0600 Subject: [PATCH 169/265] style: ruff formatting and linting fixes Signed-off-by: Josh Loecker --- main/COMO.ipynb | 5 ++--- main/como/__init__.py | 3 +-- main/como/graph/__init__.py | 20 +++++++++++++------- ruff.toml | 2 +- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/main/COMO.ipynb b/main/COMO.ipynb index 8d79c4be..82647f6e 100644 --- a/main/COMO.ipynb +++ b/main/COMO.ipynb @@ -242,8 +242,8 @@ "source": [ "from pathlib import Path\n", "\n", - "from como.rnaseq_preprocess import rnaseq_preprocess\n", "from como.data_types import RNAType\n", + "from como.rnaseq_preprocess import rnaseq_preprocess\n", "\n", "taxon_id = 9606\n", "context_names = [\"naiveB\"]\n", @@ -738,7 +738,7 @@ } }, "source": [ - "from como.merge_xomics import merge_xomics, AdjustmentMethod\n", + "from como.merge_xomics import AdjustmentMethod, merge_xomics\n", "\n", "total_rna_weight = 6\n", "mrna_weight = 6\n", @@ -889,7 +889,6 @@ "outputs": [], "source": [ "import json\n", - "import os\n", "from pathlib import Path\n", "\n", "from como.project import Config\n", diff --git a/main/como/__init__.py b/main/como/__init__.py index 660fc21f..c84ef56e 100644 --- a/main/como/__init__.py +++ b/main/como/__init__.py @@ -1,6 +1,5 @@ +from como.data_types import AdjustmentMethod, Algorithm, CobraCompartments, FilteringTechnique, LogLevel, Solver from como.utils import stringlist_to_list -from como.data_types import LogLevel, FilteringTechnique, AdjustmentMethod, Solver, Algorithm, CobraCompartments - __all__ = [ "AdjustmentMethod", diff --git a/main/como/graph/__init__.py b/main/como/graph/__init__.py index 1f6c6a22..7594db2f 100644 --- a/main/como/graph/__init__.py +++ b/main/como/graph/__init__.py @@ -1,11 +1,9 @@ from pathlib import Path -from loguru import logger + import pandas as pd -from matplotlib import pyplot as plt import seaborn as sns - - -__all__ = ["z_score_distribution"] +from loguru import logger +from matplotlib import pyplot as plt def z_score_distribution( @@ -13,12 +11,20 @@ def z_score_distribution( title: str, output_filepath: Path, ): + """Graph a z-score distribution. + + :param df: The z-score data to graph + :param title: Title to add to graph + :param output_filepath: Output PNG filepath location + :return: None + """ if output_filepath.suffix not in {".png", ".pdf", ".svg"}: logger.warning( - f"Expected .png, .pdf, or .svg suffix for output_png_filepath, got {output_filepath.suffix}. Defaulting to .pdf" + f"Expected .png, .pdf, or .svg suffix for output_png_filepath, got {output_filepath.suffix}. " + f"Defaulting to .pdf" ) output_filepath = output_filepath.with_suffix(".pdf") - logger.trace(f"Graphing z-score distribution") + logger.trace("Graphing z-score distribution") output_filepath.parent.mkdir(parents=True, exist_ok=True) output_filepath.unlink(missing_ok=True) diff --git a/ruff.toml b/ruff.toml index 3691008f..fe0bd163 100644 --- a/ruff.toml +++ b/ruff.toml @@ -1,6 +1,5 @@ line-length = 120 extend-include = ["docs/**/*.py", "tests/**/*.py", "**/*.ipynb"] -exclude = ["__init__.py"] [format] quote-style = "double" @@ -46,6 +45,7 @@ ignore = [ "D101", # allow undocumented public class "D102", # allow undocumented class method "D103", # allow undocumented public method definitions + "D104", # allow undocumented public package "F811", # allow redefinition of variables, required for pytest fixtures "S101", # allow use of `assert` in test files ] From 7e53dac311402a3f0537c03bcd408e6cff9053cc Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 16:45:46 -0600 Subject: [PATCH 170/265] fix: allow undocumented public package Signed-off-by: Josh Loecker --- ruff.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/ruff.toml b/ruff.toml index fe0bd163..eeea6f84 100644 --- a/ruff.toml +++ b/ruff.toml @@ -34,6 +34,7 @@ select = [ ignore = [ "D100", # allow undocumented public module definitions "D101", # allow undocumented public class + "D104", # allow undocumented public package "D203", # do not require one blank line before class docstring "D213", # first docstring line should be on the second line "TRY003", # allow exception messages outside the `Exception` class From bd65dbe64a2374396b4b7f432284d76fac870947 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 16:49:29 -0600 Subject: [PATCH 171/265] fix: do not create virtual environment to format notebooks Signed-off-by: Josh Loecker --- .github/workflows/continuous_integration.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 113c905d..43634ea0 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -16,12 +16,6 @@ jobs: - name: Install uv uses: astral-sh/setup-uv@v4 - - name: Create Virtual Environment - run: uv venv - - - name: Install Jupyter - run: uv pip install jupyter nbconvert - - name: Strip Notebook Output run: uv run jupyter nbconvert --clear-output --inplace "main/COMO.ipynb" From e419816af09ba122a5af38e8cb47ccfafc62299e Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 16:51:31 -0600 Subject: [PATCH 172/265] fix: use python 3.10 to evade errors Signed-off-by: Josh Loecker --- .github/workflows/continuous_integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 43634ea0..f7a3426f 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -17,7 +17,7 @@ jobs: uses: astral-sh/setup-uv@v4 - name: Strip Notebook Output - run: uv run jupyter nbconvert --clear-output --inplace "main/COMO.ipynb" + run: uv run --python 3.10 jupyter nbconvert --clear-output --inplace "main/COMO.ipynb" - name: Format Python Imports uses: astral-sh/ruff-action@v2 From 7fa8d0027c554e7dc542abecad24cae56a806e2a Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 16:57:03 -0600 Subject: [PATCH 173/265] fix: use uv tool to run nbconvert Signed-off-by: Josh Loecker --- .github/workflows/continuous_integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index f7a3426f..956807f7 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -17,7 +17,7 @@ jobs: uses: astral-sh/setup-uv@v4 - name: Strip Notebook Output - run: uv run --python 3.10 jupyter nbconvert --clear-output --inplace "main/COMO.ipynb" + run: uv tool run --from nbconvert jupyter-nbconvert --clear-output --inplace "main/COMO.ipynb" - name: Format Python Imports uses: astral-sh/ruff-action@v2 From c6f02bc9d4cbf34de1e71146d898ecf346f509cc Mon Sep 17 00:00:00 2001 From: JoshLoecker <47901540+JoshLoecker@users.noreply.github.com> Date: Sun, 12 Jan 2025 22:57:30 +0000 Subject: [PATCH 174/265] style: format code, Jupyter Notebook(s), and Python imports with `ruff` --- main/como/create_context_specific_model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 754cfc9a..701c09ef 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -81,7 +81,7 @@ def _gene_rule_logical(gpr_expression: str, level: int = 0) -> str: inner_string = inner_string.replace("[", "") inner_string = inner_string.replace("]", "") - expression_out = f"{gpr_expression[:loc_l]}{inner_string}{gpr_expression[loc_r + 1:]}" + expression_out = f"{gpr_expression[:loc_l]}{inner_string}{gpr_expression[loc_r + 1 :]}" expression_out = _gene_rule_logical(expression_out, level + 1) return expression_out From 06461507543ab414e07ddbac26149e0cb1ab2897 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 16:59:36 -0600 Subject: [PATCH 175/265] feat: expand test suite to include python 3.11 and 3.12 Signed-off-by: Josh Loecker --- .github/workflows/continuous_integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 956807f7..9169dd9b 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -56,7 +56,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [ "3.10" ] + python-version: [ "3.10", "3.11", "3.12" ] steps: - name: Checkout uses: actions/checkout@v4 From 9a72ae5b300c42681d35b4719e3d760c9582c1ed Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 17:01:07 -0600 Subject: [PATCH 176/265] fix: check if provided data is a path before checking if it exists Signed-off-by: Josh Loecker --- main/como/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/como/utils.py b/main/como/utils.py index a25c8b3e..db3886b7 100644 --- a/main/como/utils.py +++ b/main/como/utils.py @@ -149,7 +149,7 @@ async def _read_file( if not path: return None - if not path.exists(): + if isinstance(path, Path) and not path.exists(): logger.critical(f"File {path} does not exist") raise FileNotFoundError(f"File {path} does not exist") From 8259105e0fd9386c6c55dfd342dc8db856088a88 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 17:04:40 -0600 Subject: [PATCH 177/265] fix: read StringIO data instead of attempting to make dataframe from it Signed-off-by: Josh Loecker --- main/como/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/como/utils.py b/main/como/utils.py index db3886b7..b3e51361 100644 --- a/main/como/utils.py +++ b/main/como/utils.py @@ -155,7 +155,7 @@ async def _read_file( # StringIO is used if a CSV file is read using open() directly if isinstance(path, io.StringIO): - return pd.DataFrame(path, **kwargs) + return pd.read_csv(path, **kwargs) match path.suffix: case ".csv" | ".tsv": From 330ed84af5752dd4dd35493723c7bb088e53edc3 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Sun, 12 Jan 2025 17:15:30 -0600 Subject: [PATCH 178/265] fix: statsmodels version dependent on python version Signed-off-by: Josh Loecker --- pyproject.toml | 11 +++++++++++ uv.lock | 40 ++++++++++++++++++++++++++++++++-------- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c6921422..ffae336b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,6 +22,9 @@ dependencies = [ "scipy>=1.7.3", "seaborn>=0.13.2", "setuptools<60.0", + # Statsmodels >= 0.14 is required for python 3.12+ + "statsmodels>=0.13.0", + "statsmodels>=0.14.0; python_version >= '3.12'", "troppo@git+https://github.com/JoshLoecker/troppo@master", ] @@ -60,3 +63,11 @@ tag_format = "$version" version_scheme = "semver2" version_provider = "pep621" update_changelog_on_bump = true + +[tool.uv.sources] +como = { workspace = true } + +[dependency-groups] +dev = [ + "como", +] diff --git a/uv.lock b/uv.lock index 81292416..0a32e30b 100644 --- a/uv.lock +++ b/uv.lock @@ -442,6 +442,7 @@ dependencies = [ { name = "scipy" }, { name = "seaborn" }, { name = "setuptools" }, + { name = "statsmodels" }, { name = "troppo" }, ] @@ -463,6 +464,11 @@ interactive = [ { name = "jupyterlab" }, ] +[package.dev-dependencies] +dev = [ + { name = "como" }, +] + [package.metadata] requires-dist = [ { name = "aiofiles", specifier = ">=24.1.0" }, @@ -490,9 +496,14 @@ requires-dist = [ { name = "scipy", specifier = ">=1.7.3" }, { name = "seaborn", specifier = ">=0.13.2" }, { name = "setuptools", specifier = "<60.0" }, + { name = "statsmodels", specifier = ">=0.13.0" }, + { name = "statsmodels", marker = "python_full_version >= '3.12'", specifier = ">=0.14.0" }, { name = "troppo", git = "https://github.com/JoshLoecker/troppo?rev=master" }, ] +[package.metadata.requires-dev] +dev = [{ name = "como", editable = "." }] + [[package]] name = "contourpy" version = "1.2.1" @@ -2640,7 +2651,7 @@ wheels = [ [[package]] name = "statsmodels" -version = "0.13.2" +version = "0.14.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, @@ -2649,13 +2660,26 @@ dependencies = [ { name = "patsy" }, { name = "scipy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e1/4a/0eb4efa49cc352e2721e2aebfe8573264db2add195545ec3979c98040c3b/statsmodels-0.13.2.tar.gz", hash = "sha256:77dc292c9939c036a476f1770f9d08976b05437daa229928da73231147cde7d4", size = 17874260 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7b/88/684887d7c57e1d51fcf6dc5b73f7eb1fde22602a9b588784e051760abb3f/statsmodels-0.13.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3e7ca5b7e678c0bb7a24f5c735d58ac104a50eb61b17c484cce0e221a095560f", size = 9678336 }, - { url = "https://files.pythonhosted.org/packages/9a/d7/a58f9edc176f13da02e2a3b2467069f9f8a3ba960a72cbf4b228d3e378bd/statsmodels-0.13.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:066a75d5585378b2df972f81a90b9a3da5e567b7d4833300c1597438c1a35e29", size = 9134246 }, - { url = "https://files.pythonhosted.org/packages/fe/4c/150b6f9d1699f94c79df1dea6888e991c2485d22be93cae4a94166ff0efb/statsmodels-0.13.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f15f38dfc9c5c091662cb619e12322047368c67aef449c7554d9b324a15f7a94", size = 9648545 }, - { url = "https://files.pythonhosted.org/packages/6a/53/4e1fcc0d05638c0edfea18e1b09e16a2cd6ac930fe63e25d9806776c5ef0/statsmodels-0.13.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c4ccc6b4744613367e8a233bd952c8a838db8f528f9fe033bda25aa13fc7d08", size = 9954541 }, - { url = "https://files.pythonhosted.org/packages/b8/ad/820c01123f5b3d596965d5e5b274830d38bc39f93b11d76a3b53f86f45f1/statsmodels-0.13.2-cp310-cp310-win_amd64.whl", hash = "sha256:855b1cc2a91ab140b9bcf304b1731705805ce73223bf500b988804968554c0ed", size = 9138751 }, +sdist = { url = "https://files.pythonhosted.org/packages/1f/3b/963a015dd8ea17e10c7b0e2f14d7c4daec903baf60a017e756b57953a4bf/statsmodels-0.14.4.tar.gz", hash = "sha256:5d69e0f39060dc72c067f9bb6e8033b6dccdb0bae101d76a7ef0bcc94e898b67", size = 20354802 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/2c/23bf5ad9e8a77c0c8d9750512bff89e32154dea91998114118e0e147ae67/statsmodels-0.14.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7a62f1fc9086e4b7ee789a6f66b3c0fc82dd8de1edda1522d30901a0aa45e42b", size = 10216574 }, + { url = "https://files.pythonhosted.org/packages/ba/a5/2f09ab918296e534ea5d132e90efac51ae12ff15992d77539bbfca1158fa/statsmodels-0.14.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:46ac7ddefac0c9b7b607eed1d47d11e26fe92a1bc1f4d9af48aeed4e21e87981", size = 9912430 }, + { url = "https://files.pythonhosted.org/packages/93/6a/b86f8c9b799dc93e5b4a3267eb809843e6328e34248a53496b96f50d732e/statsmodels-0.14.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a337b731aa365d09bb0eab6da81446c04fde6c31976b1d8e3d3a911f0f1e07b", size = 10444673 }, + { url = "https://files.pythonhosted.org/packages/78/44/d72c634211797ed07dd8c63ced4ae11debd7a40b24ee80e79346a526194f/statsmodels-0.14.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:631bb52159117c5da42ba94bd94859276b68cab25dc4cac86475bc24671143bc", size = 10811248 }, + { url = "https://files.pythonhosted.org/packages/35/64/df81426924fcc48a0402534efa96cde13275629ae52f123189d16c4b75ff/statsmodels-0.14.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3bb2e580d382545a65f298589809af29daeb15f9da2eb252af8f79693e618abc", size = 10946447 }, + { url = "https://files.pythonhosted.org/packages/5c/f9/205130cceeda0eebd5a1a58c04e060c2f87a1d63cbbe37a9caa0fcb50c68/statsmodels-0.14.4-cp310-cp310-win_amd64.whl", hash = "sha256:9729642884147ee9db67b5a06a355890663d21f76ed608a56ac2ad98b94d201a", size = 9845796 }, + { url = "https://files.pythonhosted.org/packages/48/88/326f5f689e69d9c47a68a22ffdd20a6ea6410b53918f9a8e63380dfc181c/statsmodels-0.14.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5ed7e118e6e3e02d6723a079b8c97eaadeed943fa1f7f619f7148dfc7862670f", size = 10221032 }, + { url = "https://files.pythonhosted.org/packages/07/0b/9a0818be42f6689ebdc7a2277ea984d6299f0809d0e0277128df4f7dc606/statsmodels-0.14.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f5f537f7d000de4a1708c63400755152b862cd4926bb81a86568e347c19c364b", size = 9912219 }, + { url = "https://files.pythonhosted.org/packages/b1/f2/91c70a3b4a3e416f76ead61b04c87bc60080d634d7fa2ab893976bdd86fa/statsmodels-0.14.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa74aaa26eaa5012b0a01deeaa8a777595d0835d3d6c7175f2ac65435a7324d2", size = 10424053 }, + { url = "https://files.pythonhosted.org/packages/9d/4f/a96e682f82b675e4a6f3de8ad990587d8b1fde500a630a2aabcaabee11d8/statsmodels-0.14.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e332c2d9b806083d1797231280602340c5c913f90d4caa0213a6a54679ce9331", size = 10752529 }, + { url = "https://files.pythonhosted.org/packages/4b/c6/47549345d32da1530a819a3699f6f34f9f70733a245eeb29f5e05e53f362/statsmodels-0.14.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d9c8fa28dfd75753d9cf62769ba1fecd7e73a0be187f35cc6f54076f98aa3f3f", size = 10959003 }, + { url = "https://files.pythonhosted.org/packages/4b/e4/f9e96896278308e17dfd4f60a84826c48117674c980234ee38f59ab28a12/statsmodels-0.14.4-cp311-cp311-win_amd64.whl", hash = "sha256:a6087ecb0714f7c59eb24c22781491e6f1cfffb660b4740e167625ca4f052056", size = 9853281 }, + { url = "https://files.pythonhosted.org/packages/f5/99/654fd41a9024643ee70b239e5ebc987bf98ce9fc2693bd550bee58136564/statsmodels-0.14.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5221dba7424cf4f2561b22e9081de85f5bb871228581124a0d1b572708545199", size = 10220508 }, + { url = "https://files.pythonhosted.org/packages/67/d8/ac30cf4cf97adaa48548be57e7cf02e894f31b45fd55bf9213358d9781c9/statsmodels-0.14.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:17672b30c6b98afe2b095591e32d1d66d4372f2651428e433f16a3667f19eabb", size = 9912317 }, + { url = "https://files.pythonhosted.org/packages/e0/77/2440d551eaf27f9c1d3650e13b3821a35ad5b21d3a19f62fb302af9203e8/statsmodels-0.14.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab5e6312213b8cfb9dca93dd46a0f4dccb856541f91d3306227c3d92f7659245", size = 10301662 }, + { url = "https://files.pythonhosted.org/packages/fa/e1/60a652f18996a40a7410aeb7eb476c18da8a39792c7effe67f06883e9852/statsmodels-0.14.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4bbb150620b53133d6cd1c5d14c28a4f85701e6c781d9b689b53681effaa655f", size = 10741763 }, + { url = "https://files.pythonhosted.org/packages/81/0c/2453eec3ac25e300847d9ed97f41156de145e507391ecb5ac989e111e525/statsmodels-0.14.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bb695c2025d122a101c2aca66d2b78813c321b60d3a7c86bb8ec4467bb53b0f9", size = 10879534 }, + { url = "https://files.pythonhosted.org/packages/59/9a/e466a1b887a1441141e52dbcc98152f013d85076576da6eed2357f2016ae/statsmodels-0.14.4-cp312-cp312-win_amd64.whl", hash = "sha256:7f7917a51766b4e074da283c507a25048ad29a18e527207883d73535e0dc6184", size = 9823866 }, ] [[package]] From b6b663313041ad7ae9633fcb055eb573f18100f6 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Mon, 13 Jan 2025 09:42:01 -0600 Subject: [PATCH 179/265] fix: use tpm instead of quantile Signed-off-by: Josh Loecker --- main/como/data_types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/como/data_types.py b/main/como/data_types.py index 819f35ba..54d19b55 100644 --- a/main/como/data_types.py +++ b/main/como/data_types.py @@ -39,7 +39,7 @@ class FilteringTechnique(Enum): CPM = "cpm" ZFPKM = "zfpkm" - TPM = "quantile" + TPM = "tpm" UMI = "umi" From 21f780bcd53a2167ced1144af9aa2f7cea8e0096 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Mon, 13 Jan 2025 09:42:18 -0600 Subject: [PATCH 180/265] fix: typo Signed-off-by: Josh Loecker --- main/como/utils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/main/como/utils.py b/main/como/utils.py index b3e51361..b28ab3ca 100644 --- a/main/como/utils.py +++ b/main/como/utils.py @@ -123,11 +123,11 @@ async def _format_determination( :return: A pandas DataFrame """ requested_output = [requested_output] if isinstance(requested_output, Output) else requested_output - cohersion = (await biodbnet.db_find(values=input_values, output_db=requested_output, taxon=taxon)).drop( + coercion = (await biodbnet.db_find(values=input_values, output_db=requested_output, taxon=taxon)).drop( columns=["Input Type"] ) - cohersion.columns = pd.Index(["input_value", *[o.value.replace(" ", "_").lower() for o in requested_output]]) - return cohersion + coercion.columns = pd.Index(["input_value", *[o.value.replace(" ", "_").lower() for o in requested_output]]) + return coercion async def _read_file( From b119787ca531e1f4c23147fd3f747f8128ae35fb Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Mon, 13 Jan 2025 09:42:41 -0600 Subject: [PATCH 181/265] chore: update uv lock Signed-off-by: Josh Loecker --- uv.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/uv.lock b/uv.lock index 0a32e30b..627dcf41 100644 --- a/uv.lock +++ b/uv.lock @@ -1,9 +1,9 @@ version = 1 requires-python = ">=3.10, <3.13" resolution-markers = [ - "python_full_version < '3.11'", - "python_full_version == '3.11.*'", "python_full_version >= '3.12'", + "python_full_version == '3.11.*'", + "python_full_version < '3.11'", ] [[package]] From a441231f29f22d34870ec7e9482b2dea548467f0 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Mon, 13 Jan 2025 09:44:01 -0600 Subject: [PATCH 182/265] chore: code re-arrangement Signed-off-by: Josh Loecker --- main/como/data_types.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/main/como/data_types.py b/main/como/data_types.py index 54d19b55..9b633999 100644 --- a/main/como/data_types.py +++ b/main/como/data_types.py @@ -59,11 +59,6 @@ class LogLevel(Enum): CRITICAL = 50 -class PeakIdentificationParameters(NamedTuple): - height: float - distance: float - - class RNAType(Enum): TRNA = "total" MRNA = "mrna" @@ -86,6 +81,11 @@ class SourceTypes(Enum): PROTEOMICS = "proteomics" +class PeakIdentificationParameters(NamedTuple): + height: float + distance: float + + class CobraCompartments: """Convert from compartment "long-hand" to "short-hand". From 09e1852e385024ece32860d644168d178ed33358 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Mon, 13 Jan 2025 09:57:39 -0600 Subject: [PATCH 183/265] chore: remove aiofiles as a dependency Signed-off-by: Josh Loecker --- pyproject.toml | 2 -- uv.lock | 2 -- 2 files changed, 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index ffae336b..af0963d7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,6 @@ name = "COMO" dynamic = ["version"] requires-python = ">=3.10,<3.13" dependencies = [ - "aiofiles>=24.1.0", "aioftp>=0.23.1", "cobamp@git+https://github.com/JoshLoecker/cobamp@master", "cobra>=0.28.0", @@ -22,7 +21,6 @@ dependencies = [ "scipy>=1.7.3", "seaborn>=0.13.2", "setuptools<60.0", - # Statsmodels >= 0.14 is required for python 3.12+ "statsmodels>=0.13.0", "statsmodels>=0.14.0; python_version >= '3.12'", "troppo@git+https://github.com/JoshLoecker/troppo@master", diff --git a/uv.lock b/uv.lock index 627dcf41..1a227653 100644 --- a/uv.lock +++ b/uv.lock @@ -427,7 +427,6 @@ name = "como" version = "1.11.1" source = { editable = "." } dependencies = [ - { name = "aiofiles" }, { name = "aioftp" }, { name = "cobamp" }, { name = "cobra" }, @@ -471,7 +470,6 @@ dev = [ [package.metadata] requires-dist = [ - { name = "aiofiles", specifier = ">=24.1.0" }, { name = "aioftp", specifier = ">=0.23.1" }, { name = "cobamp", git = "https://github.com/JoshLoecker/cobamp?rev=master" }, { name = "cobra", specifier = ">=0.28.0" }, From 80f32d425397fa2b68d6f25b9b09d57a4e5bd2a3 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 14 Jan 2025 14:17:10 -0600 Subject: [PATCH 184/265] fix: renamed RNAType.(trna,mrna) to RNAType.(TRNA,MRNA) Signed-off-by: Josh Loecker --- main/como/rnaseq_preprocess.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index 013d7f49..2a7b2bd5 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -602,9 +602,9 @@ async def _process( ): rna_types: list[tuple[RNAType, Path, Path]] = [] if output_trna_config_filepath: - rna_types.append((RNAType.trna, output_trna_config_filepath, output_trna_matrix_filepath)) + rna_types.append((RNAType.TRNA, output_trna_config_filepath, output_trna_matrix_filepath)) if output_mrna_config_filepath: - rna_types.append((RNAType.mrna, output_mrna_config_filepath, output_mrna_matrix_filepath)) + rna_types.append((RNAType.MRNA, output_mrna_config_filepath, output_mrna_matrix_filepath)) # if provided, iterate through como-input specific directories tasks = [] From 2c1687b36cb637b2c9ce6129e14e213634c93d47 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 14 Jan 2025 14:18:14 -0600 Subject: [PATCH 185/265] fix: re-attempt processing if JSON decode error occurs Signed-off-by: Josh Loecker --- main/como/rnaseq_preprocess.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index 2a7b2bd5..344a07b5 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -1,6 +1,7 @@ from __future__ import annotations import asyncio +import json import re import sys from dataclasses import dataclass, field @@ -521,11 +522,16 @@ async def _create_gene_info_file( async def read_counts(file: Path) -> list[str]: data = await _read_file(file, h5ad_as_df=False) - conversion = await ( - ensembl_to_gene_id_and_symbol(ids=data["ensembl_gene_id"].tolist(), taxon=taxon) - if isinstance(data, pd.DataFrame) - else gene_symbol_to_ensembl_and_gene_id(symbols=data.var_names.tolist(), taxon=taxon) - ) + + try: + conversion = await ( + ensembl_to_gene_id_and_symbol(ids=data["ensembl_gene_id"].tolist(), taxon=taxon) + if isinstance(data, pd.DataFrame) + else gene_symbol_to_ensembl_and_gene_id(symbols=data.var_names.tolist(), taxon=taxon) + ) + except json.JSONDecodeError: + logger.warning(f"Got a JSON decode error for file '{counts_matrix_filepaths}', exiting") + exit() # Remove NA values from entrez_gene_id dataframe column return conversion["entrez_gene_id"].dropna().tolist() From 0f317f31e76b0e20dd4ecf32614c00fe72566e5b Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 14 Jan 2025 14:18:39 -0600 Subject: [PATCH 186/265] refactor: remove dependency on aiofiles Signed-off-by: Josh Loecker --- main/como/rnaseq_preprocess.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index 344a07b5..943476b9 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -10,7 +10,6 @@ from pathlib import Path from typing import Literal -import aiofiles import numpy as np import pandas as pd from fast_bioservices.biothings.mygene import MyGene @@ -43,17 +42,21 @@ async def build_from_tab(cls, filepath: Path) -> _STARinformation: level=LogLevel.ERROR, ) - async with aiofiles.open(filepath) as i_stream: - unmapped = await i_stream.readline() - multimapping = await i_stream.readline() - no_feature = await i_stream.readline() - ambiguous = await i_stream.readline() + with filepath.open("r") as i_stream: + unmapped, multimapping, no_feature, ambiguous = await asyncio.gather( + *[ + asyncio.to_thread(i_stream.readline), + asyncio.to_thread(i_stream.readline), + asyncio.to_thread(i_stream.readline), + asyncio.to_thread(i_stream.readline), + ] + ) num_unmapped = [int(i) for i in unmapped.rstrip("\n").split("\t")[1:]] num_multimapping = [int(i) for i in multimapping.rstrip("\n").split("\t")[1:]] num_no_feature = [int(i) for i in no_feature.rstrip("\n").split("\t")[1:]] num_ambiguous = [int(i) for i in ambiguous.rstrip("\n").split("\t")[1:]] - remainder = await i_stream.read() + remainder = await asyncio.to_thread(i_stream.read) df = await _read_file(StringIO(remainder), sep="\t", header=None) df.columns = [ From 2229c51d64f52b8bbe49420269c75d4a6be33a9e Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 14 Jan 2025 14:18:51 -0600 Subject: [PATCH 187/265] fix: do not call listify twice Signed-off-by: Josh Loecker --- main/como/rnaseq_preprocess.py | 1 - 1 file changed, 1 deletion(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index 943476b9..12a5b82a 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -702,7 +702,6 @@ async def rnaseq_preprocess( else output_mrna_count_matrix_filepath ) - input_matrix_filepath = _listify(input_matrix_filepath) await _process( context_name=context_name, taxon=taxon, From 9a6a42dc51987141883b91e808b6890ec072c958 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 14 Jan 2025 14:19:14 -0600 Subject: [PATCH 188/265] refactor: remove dependency on aiofiles Signed-off-by: Josh Loecker --- main/como/combine_distributions.py | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index f7bd19d3..3571f122 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -3,7 +3,6 @@ import asyncio from pathlib import Path -import aiofiles.os import numpy as np import pandas as pd from loguru import logger @@ -34,12 +33,8 @@ async def _combine_z_distribution_for_batch( weighted_z_floor: int, weighted_z_ceiling: int, ) -> pd.DataFrame: - await asyncio.gather( - *[ - aiofiles.os.makedirs(output_combined_matrix_filepath.parent.as_posix(), exist_ok=True), - aiofiles.os.makedirs(output_figure_dirpath.as_posix(), exist_ok=True), - ] - ) + output_combined_matrix_filepath.parent.mkdir(parents=True, exist_ok=True) + output_figure_dirpath.mkdir(parents=True, exist_ok=True) logger.trace( f"Combining z-score distributions: batch #{batch.batch_num}, " @@ -102,12 +97,8 @@ async def _combine_z_distribution_for_source( merged_source_data.columns = ["ensembl_gene_id", "combine_z"] return merged_source_data - await asyncio.gather( - *[ - aiofiles.os.makedirs(output_combined_matrix_filepath.parent.as_posix(), exist_ok=True), - aiofiles.os.makedirs(output_figure_filepath.parent.as_posix(), exist_ok=True), - ] - ) + output_combined_matrix_filepath.parent.mkdir(parents=True, exist_ok=True) + output_figure_filepath.parent.mkdir(parents=True, exist_ok=True) logger.trace(f"Found {_num_columns(merged_source_data) - 1} samples for context '{context_name}' to combine") values = merged_source_data.iloc[:, 1:].values From f288015d7c1a4294fff50f3aa29906df85ec76e9 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 14 Jan 2025 14:20:03 -0600 Subject: [PATCH 189/265] refactor: allow providing a list of model filepaths to write to Signed-off-by: Josh Loecker --- main/como/create_context_specific_model.py | 58 +++++++++++++--------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 701c09ef..0e408be0 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -547,20 +547,21 @@ async def _collect_boundary_reactions(path: Path) -> _BoundaryReactions: ) -async def _write_model_to_disk( - model: cobra.Model, - output_directory: Path, - context_name: str, - output_filetypes: list[str], - algorithm: Algorithm, -) -> None: - output_directory.mkdir(parents=True, exist_ok=True) - if "mat" in output_filetypes: - cobra.io.save_matlab_model(model, (output_directory / f"{context_name}_SpecificModel_{algorithm.value}.mat")) - if "json" in output_filetypes: - cobra.io.save_json_model(model, (output_directory / f"{context_name}_SpecificModel_{algorithm.value}.json")) - if "xml" in output_filetypes: - cobra.io.write_sbml_model(model, (output_directory / f"{context_name}_SpecificModel_{algorithm.value}.xml")) +def _write_model_to_disk(context_name: str, model: cobra.Model, output_filepaths: list[Path]) -> None: + for path in output_filepaths: + if path.suffix == ".mat": + cobra.io.save_matlab_model(model=model, file_name=path) + elif path.suffix == ".json": + cobra.io.save_json_model(model=model, filename=path, pretty=True) + elif path.suffix in {".sbml", ".xml"}: + cobra.io.write_sbml_model(cobra_model=model, filename=path) + else: + _log_and_raise_error( + f"Invalid output model filetype. Should be one of .xml, .sbml, .mat, or .json. Got '{path.suffix}'", + error=ValueError, + level=LogLevel.ERROR, + ) + logger.success(f"Saved metabolic model for context '{context_name}' to '{path}'") async def create_context_specific_model( # noqa: C901 @@ -568,8 +569,8 @@ async def create_context_specific_model( # noqa: C901 reference_model: Path, active_genes_filepath: Path, output_infeasible_reactions_filepath: Path, - output_model_dirpath: Path, output_flux_result_filepath: Path, + output_model_filepaths: Path | list[Path], output_filetypes: list[str] | None = None, output_fastcore_expression_index_filepath: Path | None = None, objective: str = "biomass_reaction", @@ -585,6 +586,23 @@ async def create_context_specific_model( # noqa: C901 ): """Create a context-specific model using the provided data.""" _set_up_logging(level=log_level, location=log_location) + output_model_filepaths = ( + [output_model_filepaths] if isinstance(output_model_filepaths, Path) else output_model_filepaths + ) + for path in output_model_filepaths: + if path.suffix not in {".mat", ".xml", ".sbml", ".json"}: + _log_and_raise_error( + f"Invalid output model filetype. Should be one of .xml, .sbml, .mat, or .json. Got '{path.suffix}'", + error=ValueError, + level=LogLevel.ERROR, + ) + if len(output_model_filepaths) != len(output_model_filepaths): + _log_and_raise_error( + "The number of output model filepaths must be the same as the number of output flux result filepaths", + error=ValueError, + level=LogLevel.ERROR, + ) + if not reference_model.exists(): _log_and_raise_error( f"Reference model not found at {reference_model}", @@ -685,15 +703,7 @@ async def create_context_specific_model( # noqa: C901 fastcore_df.dropna(inplace=True) fastcore_df.to_csv(output_fastcore_expression_index_filepath, index=False) - await _write_model_to_disk( - model=build_results.model, - output_directory=output_model_dirpath, - context_name=context_name, - output_filetypes=output_filetypes, - algorithm=algorithm, - ) - - logger.success(f"Saved metabolic model for context '{context_name}' to {output_model_dirpath}") + _write_model_to_disk(context_name=context_name, model=build_results.model, output_filepaths=output_model_filepaths) logger.debug(f"Number of Genes: {len(build_results.model.genes):,}") logger.debug(f"Number of Metabolites: {len(build_results.model.metabolites):,}") logger.debug(f"Number of Reactions: {len(build_results.model.reactions):,}") From c0d38168f407aad1d7857ab1f43488bbc29d4111 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 14 Jan 2025 14:20:28 -0600 Subject: [PATCH 190/265] fix: check that license information is present if using gurobi Signed-off-by: Josh Loecker --- main/como/create_context_specific_model.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 0e408be0..a375c815 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -678,6 +678,28 @@ async def create_context_specific_model( # noqa: C901 ) force_rxns = df["abbreviation"].tolist() + # Test that gurobi is using a valid license file + if solver == Solver.GUROBI: + # test if gurobi is available + try: + import gurobipy as gp + except ImportError as e: + logger.error( + "The gurobi solver requires the gurobipy package to be installed. " + "Please install gurobipy and try again. " + "This can be done by installing the 'gurobi' optional dependency." + ) + raise ImportError from e + + env = gp.Env() + if env.getParam("WLSACCESSID") == "" or env.getParam("WLSSECRET") == "": + logger.critical( + "You have requested to use the Gurobi solver but license information cannot be found. " + "COMO will continue, but it is HIGHLY unlikely the resulting model will be valid." + ) + # remove gurobi-related information, it is no longer required + del env, gp + logger.info(f"Creating '{context_name}' model using '{algorithm.value}' reconstruction and '{solver.value}' solver") build_results: _BuildResults = await _build_model( general_model_file=reference_model, From df86903095e98193b9f5b24c5e536acea8f7f27f Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 14 Jan 2025 14:20:40 -0600 Subject: [PATCH 191/265] feat: add NONE for no logging Signed-off-by: Josh Loecker --- main/como/data_types.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main/como/data_types.py b/main/como/data_types.py index 9b633999..f9c11ca5 100644 --- a/main/como/data_types.py +++ b/main/como/data_types.py @@ -57,6 +57,7 @@ class LogLevel(Enum): WARNING = 30 ERROR = 40 CRITICAL = 50 + NONE = 100 class RNAType(Enum): From f9250789fa17446711cc9513b476f6d91a3aba8e Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 14 Jan 2025 14:22:30 -0600 Subject: [PATCH 192/265] refactor: remove dependency on aiofiles Signed-off-by: Josh Loecker --- main/como/utils.py | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/main/como/utils.py b/main/como/utils.py index b28ab3ca..22652f6a 100644 --- a/main/como/utils.py +++ b/main/como/utils.py @@ -3,16 +3,13 @@ import asyncio import contextlib import functools -import inspect import io import sys from collections.abc import Iterator from concurrent.futures import ThreadPoolExecutor from io import TextIOWrapper from pathlib import Path -from typing import Union -import aiofiles import numpy.typing as npt import pandas as pd import scanpy as sc @@ -160,21 +157,13 @@ async def _read_file( match path.suffix: case ".csv" | ".tsv": kwargs.setdefault("sep", "," if path.suffix == ".csv" else "\t") - async with aiofiles.open(path) as f: - content = await f.read() + with path.open("r") as i_stream: + content = i_stream.read() return pd.read_csv(io.StringIO(content), **kwargs) case ".xlsx" | ".xls": - loop = asyncio.get_running_loop() - with ThreadPoolExecutor(max_workers=1) as pool: - # pass kwargs as args - func = functools.partial(pd.read_excel, **kwargs) - return await loop.run_in_executor(pool, func, path) + return pd.read_excel(path, **kwargs) case ".h5ad": - loop = asyncio.get_running_loop() - with ThreadPoolExecutor(max_workers=1) as pool: - func = functools.partial(sc.read_h5ad, **kwargs) - adata: sc.AnnData = await loop.run_in_executor(pool, func, path) - + adata: sc.AnnData = sc.read_h5ad(path, **kwargs) if h5ad_as_df: df = adata.to_df().T df.index.name = "gene_symbol" From 13aa4aece7cf177e1572f446fbada482ce0ccf3d Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 31 Jan 2025 13:37:30 -0600 Subject: [PATCH 193/265] style: ruff formatting --- main/como/cluster_rnaseq.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/main/como/cluster_rnaseq.py b/main/como/cluster_rnaseq.py index 818a45bc..2fb96cdc 100644 --- a/main/como/cluster_rnaseq.py +++ b/main/como/cluster_rnaseq.py @@ -36,7 +36,9 @@ def __post_init__(self): # noqa: C901, ignore too complex if (isdigit(self.min_active_count) and int(self.min_active_count) < 0) or self.min_active_count != "default": _log_and_raise_error( - "min_active_count must be either 'default' or an integer > 0", error=ValueError, level=LogLevel.ERROR + "min_active_count must be either 'default' or an integer > 0", + error=ValueError, + level=LogLevel.ERROR, ) if (isdigit(self.quantile) and 0 > int(self.quantile) > 100) or self.quantile != "default": From 1ac47f0bf6e9241d871ce0ae203bc24ab256d70c Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 31 Jan 2025 13:39:20 -0600 Subject: [PATCH 194/265] fix: make parent directories before saving files --- main/como/create_context_specific_model.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index a375c815..eb5796fc 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -549,6 +549,7 @@ async def _collect_boundary_reactions(path: Path) -> _BoundaryReactions: def _write_model_to_disk(context_name: str, model: cobra.Model, output_filepaths: list[Path]) -> None: for path in output_filepaths: + path.parent.mkdir(parents=True, exist_ok=True) if path.suffix == ".mat": cobra.io.save_matlab_model(model=model, file_name=path) elif path.suffix == ".json": From 72c363002c6ef254447ca716a0f253b53f20252e Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 31 Jan 2025 13:40:43 -0600 Subject: [PATCH 195/265] refactor: use critical log instead of warning --- main/como/rnaseq_preprocess.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index 12a5b82a..40e8a01d 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -533,8 +533,11 @@ async def read_counts(file: Path) -> list[str]: else gene_symbol_to_ensembl_and_gene_id(symbols=data.var_names.tolist(), taxon=taxon) ) except json.JSONDecodeError: - logger.warning(f"Got a JSON decode error for file '{counts_matrix_filepaths}', exiting") - exit() + _log_and_raise_error( + f"Got a JSO decode error for file '{counts_matrix_filepaths}'", + error=ValueError, + level=LogLevel.CRITICAL, + ) # Remove NA values from entrez_gene_id dataframe column return conversion["entrez_gene_id"].dropna().tolist() From 8be741d1628578bf5636d234a01efbeb3aa7ecab Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 31 Jan 2025 13:43:14 -0600 Subject: [PATCH 196/265] refactor: reset exection output and count --- main/COMO.ipynb | 98 ++++++++----------------------------------------- 1 file changed, 15 insertions(+), 83 deletions(-) diff --git a/main/COMO.ipynb b/main/COMO.ipynb index 82647f6e..f86b9bd1 100644 --- a/main/COMO.ipynb +++ b/main/COMO.ipynb @@ -233,12 +233,14 @@ }, { "cell_type": "code", + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2024-12-16T20:09:29.761117Z", "start_time": "2024-12-16T20:09:29.754605Z" } }, + "outputs": [], "source": [ "from pathlib import Path\n", "\n", @@ -265,9 +267,7 @@ "proteomics_metadata_filepath = Path(\"data/config_sheets/proteomics_config.xlsx\")\n", "\n", "# Output Components\n" - ], - "outputs": [], - "execution_count": 11 + ] }, { "cell_type": "markdown", @@ -282,12 +282,14 @@ }, { "cell_type": "code", + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2024-12-16T20:07:08.331063Z", "start_time": "2024-12-16T20:06:10.188429Z" } }, + "outputs": [], "source": [ "for context in context_names:\n", " if context not in {*trna_matrix_filepath, *mrna_matrix_filepath}:\n", @@ -305,20 +307,7 @@ " cache=True,\n", " log_level=\"INFO\",\n", " )" - ], - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001B[32m2024-12-16 14:06:13\u001B[0m | \u001B[32m\u001B[1mSUCCESS \u001B[0m | \u001B[36mcomo.rnaseq_preprocess\u001B[0m:\u001B[36m277\u001B[0m - \u001B[32m\u001B[1mWrote gene count matrix for 'mrna' RNA at '/Users/joshl/Projects/COMO/main/data/results/naiveB/polya-rna/polyarna_naiveB.csv'\u001B[0m\n", - "\u001B[32m2024-12-16 14:06:13\u001B[0m | \u001B[32m\u001B[1mSUCCESS \u001B[0m | \u001B[36mcomo.rnaseq_preprocess\u001B[0m:\u001B[36m277\u001B[0m - \u001B[32m\u001B[1mWrote gene count matrix for 'total' RNA at '/Users/joshl/Projects/COMO/main/data/results/naiveB/total-rna/totalrna_naiveB.csv'\u001B[0m\n", - "\u001B[32m2024-12-16 14:06:13\u001B[0m | \u001B[1mINFO \u001B[0m | \u001B[36mcomo.rnaseq_preprocess\u001B[0m:\u001B[36m468\u001B[0m - \u001B[1mFetching gene info (this may take 1-5 minutes depending on the number of genes and your internet connection)\u001B[0m\n", - "\u001B[32m2024-12-16 14:07:08\u001B[0m | \u001B[32m\u001B[1mSUCCESS \u001B[0m | \u001B[36mcomo.rnaseq_preprocess\u001B[0m:\u001B[36m505\u001B[0m - \u001B[32m\u001B[1mGene Info file written at '/Users/joshl/Projects/COMO/main/data/results/naiveB/gene_info.csv'\u001B[0m\n" - ] - } - ], - "execution_count": 8 + ] }, { "cell_type": "markdown", @@ -392,12 +381,14 @@ }, { "cell_type": "code", + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2024-12-16T20:08:00.274368Z", "start_time": "2024-12-16T20:07:48.637980Z" } }, + "outputs": [], "source": [ "from como.rnaseq_gen import FilteringTechnique, rnaseq_gen\n", "\n", @@ -427,20 +418,7 @@ " technique=technique,\n", " cutoff=cutoff\n", " )" - ], - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/joshl/Projects/COMO/main/como/rnaseq_gen.py:430: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n", - " mega_df = pd.concat([mega_df, df], ignore_index=True)\n", - "\u001B[32m2024-12-16 14:08:00\u001B[0m | \u001B[1mINFO \u001B[0m | \u001B[36mcomo.rnaseq_gen\u001B[0m:\u001B[36m691\u001B[0m - \u001B[1mnaiveB - Found 9492 expressed and 9492 confidently expressed genes\u001B[0m\n", - "\u001B[32m2024-12-16 14:08:00\u001B[0m | \u001B[32m\u001B[1mSUCCESS \u001B[0m | \u001B[36mcomo.rnaseq_gen\u001B[0m:\u001B[36m694\u001B[0m - \u001B[32m\u001B[1mWrote boolean matrix to data/results/naiveB/total-rna/totalrna_naiveB.csv\u001B[0m\n" - ] - } - ], - "execution_count": 9 + ] }, { "cell_type": "markdown", @@ -463,12 +441,14 @@ }, { "cell_type": "code", + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2024-12-16T20:15:16.139743Z", "start_time": "2024-12-16T20:15:15.998158Z" } }, + "outputs": [], "source": [ "from como.rnaseq_gen import FilteringTechnique, rnaseq_gen\n", "\n", @@ -497,34 +477,7 @@ " technique=technique,\n", " cutoff=cutoff\n", " )" - ], - "outputs": [ - { - "ename": "KeyError", - "evalue": "'ensembl_gene_id'", - "output_type": "error", - "traceback": [ - "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", - "\u001B[0;31mKeyError\u001B[0m Traceback (most recent call last)", - "File \u001B[0;32m~/Projects/COMO/.venv/lib/python3.10/site-packages/pandas/core/indexes/base.py:3805\u001B[0m, in \u001B[0;36mIndex.get_loc\u001B[0;34m(self, key)\u001B[0m\n\u001B[1;32m 3804\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[0;32m-> 3805\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_engine\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mget_loc\u001B[49m\u001B[43m(\u001B[49m\u001B[43mcasted_key\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 3806\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mKeyError\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m err:\n", - "File \u001B[0;32mindex.pyx:167\u001B[0m, in \u001B[0;36mpandas._libs.index.IndexEngine.get_loc\u001B[0;34m()\u001B[0m\n", - "File \u001B[0;32mindex.pyx:196\u001B[0m, in \u001B[0;36mpandas._libs.index.IndexEngine.get_loc\u001B[0;34m()\u001B[0m\n", - "File \u001B[0;32mpandas/_libs/hashtable_class_helper.pxi:7081\u001B[0m, in \u001B[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001B[0;34m()\u001B[0m\n", - "File \u001B[0;32mpandas/_libs/hashtable_class_helper.pxi:7089\u001B[0m, in \u001B[0;36mpandas._libs.hashtable.PyObjectHashTable.get_item\u001B[0;34m()\u001B[0m\n", - "\u001B[0;31mKeyError\u001B[0m: 'ensembl_gene_id'", - "\nThe above exception was the direct cause of the following exception:\n", - "\u001B[0;31mKeyError\u001B[0m Traceback (most recent call last)", - "Cell \u001B[0;32mIn[15], line 13\u001B[0m\n\u001B[1;32m 11\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m context \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;129;01min\u001B[39;00m mrna_matrix_filepath:\n\u001B[1;32m 12\u001B[0m \u001B[38;5;28;01mcontinue\u001B[39;00m\n\u001B[0;32m---> 13\u001B[0m \u001B[38;5;28;01mawait\u001B[39;00m rnaseq_gen(\n\u001B[1;32m 14\u001B[0m context_name\u001B[38;5;241m=\u001B[39mcontext,\n\u001B[1;32m 15\u001B[0m input_rnaseq_filepath\u001B[38;5;241m=\u001B[39mmrna_matrix_filepath[context],\n\u001B[1;32m 16\u001B[0m input_gene_info_filepath\u001B[38;5;241m=\u001B[39mgene_info_filepath[context],\n\u001B[1;32m 17\u001B[0m output_rnaseq_filepath\u001B[38;5;241m=\u001B[39mmrna_matrix_filepath[context],\n\u001B[1;32m 18\u001B[0m prep\u001B[38;5;241m=\u001B[39mRNAPrepMethod\u001B[38;5;241m.\u001B[39mMRNA,\n\u001B[1;32m 19\u001B[0m taxon\u001B[38;5;241m=\u001B[39mtaxon_id,\n\u001B[1;32m 20\u001B[0m input_metadata_filepath\u001B[38;5;241m=\u001B[39mmrna_metadata_filepath,\n\u001B[1;32m 21\u001B[0m replicate_ratio\u001B[38;5;241m=\u001B[39mreplicate_ratio,\n\u001B[1;32m 22\u001B[0m high_replicate_ratio\u001B[38;5;241m=\u001B[39mhigh_confidence_replicate_ratio,\n\u001B[1;32m 23\u001B[0m batch_ratio\u001B[38;5;241m=\u001B[39mbatch_ratio,\n\u001B[1;32m 24\u001B[0m high_batch_ratio\u001B[38;5;241m=\u001B[39mhigh_confidence_batch_ratio,\n\u001B[1;32m 25\u001B[0m technique\u001B[38;5;241m=\u001B[39mtechnique,\n\u001B[1;32m 26\u001B[0m cutoff\u001B[38;5;241m=\u001B[39mcutoff\n\u001B[1;32m 27\u001B[0m )\n", - "File \u001B[0;32m~/Projects/COMO/main/como/rnaseq_gen.py:787\u001B[0m, in \u001B[0;36mrnaseq_gen\u001B[0;34m(context_name, input_rnaseq_filepath, input_gene_info_filepath, output_rnaseq_filepath, prep, taxon, input_metadata_filepath, input_metadata_df, replicate_ratio, high_replicate_ratio, batch_ratio, high_batch_ratio, technique, cutoff)\u001B[0m\n\u001B[1;32m 784\u001B[0m logger\u001B[38;5;241m.\u001B[39mdebug(\u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mStarting \u001B[39m\u001B[38;5;124m'\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext_name\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m'\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n\u001B[1;32m 785\u001B[0m output_rnaseq_filepath\u001B[38;5;241m.\u001B[39mparent\u001B[38;5;241m.\u001B[39mmkdir(parents\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mTrue\u001B[39;00m, exist_ok\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mTrue\u001B[39;00m)\n\u001B[0;32m--> 787\u001B[0m \u001B[38;5;28;01mawait\u001B[39;00m _save_rnaseq_tests(\n\u001B[1;32m 788\u001B[0m context_name\u001B[38;5;241m=\u001B[39mcontext_name,\n\u001B[1;32m 789\u001B[0m rnaseq_matrix\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mawait\u001B[39;00m _read_counts(input_rnaseq_filepath),\n\u001B[1;32m 790\u001B[0m metadata_df\u001B[38;5;241m=\u001B[39minput_metadata_df \u001B[38;5;129;01mor\u001B[39;00m \u001B[38;5;28;01mawait\u001B[39;00m _create_metadata_df(input_metadata_filepath),\n\u001B[1;32m 791\u001B[0m gene_info_df\u001B[38;5;241m=\u001B[39mpd\u001B[38;5;241m.\u001B[39mread_csv(input_gene_info_filepath),\n\u001B[1;32m 792\u001B[0m output_filepath\u001B[38;5;241m=\u001B[39moutput_rnaseq_filepath,\n\u001B[1;32m 793\u001B[0m prep\u001B[38;5;241m=\u001B[39mprep,\n\u001B[1;32m 794\u001B[0m taxon\u001B[38;5;241m=\u001B[39mtaxon,\n\u001B[1;32m 795\u001B[0m replicate_ratio\u001B[38;5;241m=\u001B[39mreplicate_ratio,\n\u001B[1;32m 796\u001B[0m batch_ratio\u001B[38;5;241m=\u001B[39mbatch_ratio,\n\u001B[1;32m 797\u001B[0m high_replicate_ratio\u001B[38;5;241m=\u001B[39mhigh_replicate_ratio,\n\u001B[1;32m 798\u001B[0m high_batch_ratio\u001B[38;5;241m=\u001B[39mhigh_batch_ratio,\n\u001B[1;32m 799\u001B[0m technique\u001B[38;5;241m=\u001B[39mtechnique,\n\u001B[1;32m 800\u001B[0m cut_off\u001B[38;5;241m=\u001B[39mcutoff,\n\u001B[1;32m 801\u001B[0m )\n", - "File \u001B[0;32m~/Projects/COMO/main/como/rnaseq_gen.py:645\u001B[0m, in \u001B[0;36m_save_rnaseq_tests\u001B[0;34m(context_name, rnaseq_matrix, metadata_df, gene_info_df, output_filepath, prep, taxon, replicate_ratio, batch_ratio, high_replicate_ratio, high_batch_ratio, technique, cut_off)\u001B[0m\n\u001B[1;32m 636\u001B[0m \u001B[38;5;250m\u001B[39m\u001B[38;5;124;03m\"\"\"Save the results of the RNA-Seq tests to a CSV file.\"\"\"\u001B[39;00m\n\u001B[1;32m 637\u001B[0m filtering_options \u001B[38;5;241m=\u001B[39m _FilteringOptions(\n\u001B[1;32m 638\u001B[0m replicate_ratio\u001B[38;5;241m=\u001B[39mreplicate_ratio,\n\u001B[1;32m 639\u001B[0m batch_ratio\u001B[38;5;241m=\u001B[39mbatch_ratio,\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 642\u001B[0m high_batch_ratio\u001B[38;5;241m=\u001B[39mhigh_batch_ratio,\n\u001B[1;32m 643\u001B[0m )\n\u001B[0;32m--> 645\u001B[0m read_counts_results: _ReadMatrixResults \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mawait\u001B[39;00m _build_matrix_results(\n\u001B[1;32m 646\u001B[0m matrix\u001B[38;5;241m=\u001B[39mrnaseq_matrix,\n\u001B[1;32m 647\u001B[0m gene_info\u001B[38;5;241m=\u001B[39mgene_info_df,\n\u001B[1;32m 648\u001B[0m metadata_df\u001B[38;5;241m=\u001B[39mmetadata_df,\n\u001B[1;32m 649\u001B[0m taxon\u001B[38;5;241m=\u001B[39mtaxon,\n\u001B[1;32m 650\u001B[0m )\n\u001B[1;32m 651\u001B[0m metrics \u001B[38;5;241m=\u001B[39m read_counts_results\u001B[38;5;241m.\u001B[39mmetrics\n\u001B[1;32m 652\u001B[0m entrez_gene_ids \u001B[38;5;241m=\u001B[39m read_counts_results\u001B[38;5;241m.\u001B[39mentrez_gene_ids\n", - "File \u001B[0;32m~/Projects/COMO/main/como/rnaseq_gen.py:175\u001B[0m, in \u001B[0;36m_build_matrix_results\u001B[0;34m(matrix, gene_info, metadata_df, taxon)\u001B[0m\n\u001B[1;32m 167\u001B[0m \u001B[38;5;250m\u001B[39m\u001B[38;5;124;03m\"\"\"Read the counts matrix and returns the results.\u001B[39;00m\n\u001B[1;32m 168\u001B[0m \n\u001B[1;32m 169\u001B[0m \u001B[38;5;124;03m:param matrix: The gene counts matrix to process\u001B[39;00m\n\u001B[0;32m (...)\u001B[0m\n\u001B[1;32m 172\u001B[0m \u001B[38;5;124;03m:return: A dataclass `ReadMatrixResults`\u001B[39;00m\n\u001B[1;32m 173\u001B[0m \u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[1;32m 174\u001B[0m gene_info \u001B[38;5;241m=\u001B[39m gene_info_migrations(gene_info)\n\u001B[0;32m--> 175\u001B[0m conversion \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mawait\u001B[39;00m ensembl_to_gene_id_and_symbol(ids\u001B[38;5;241m=\u001B[39m\u001B[43mmatrix\u001B[49m\u001B[43m[\u001B[49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43mensembl_gene_id\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[43m]\u001B[49m\u001B[38;5;241m.\u001B[39mtolist(), taxon\u001B[38;5;241m=\u001B[39mtaxon)\n\u001B[1;32m 176\u001B[0m matrix \u001B[38;5;241m=\u001B[39m matrix\u001B[38;5;241m.\u001B[39mmerge(conversion, on\u001B[38;5;241m=\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mensembl_gene_id\u001B[39m\u001B[38;5;124m\"\u001B[39m, how\u001B[38;5;241m=\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mleft\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n\u001B[1;32m 178\u001B[0m \u001B[38;5;66;03m# Only include Entrez and Ensembl Gene IDs that are present in `gene_info`\u001B[39;00m\n", - "File \u001B[0;32m~/Projects/COMO/.venv/lib/python3.10/site-packages/pandas/core/frame.py:4102\u001B[0m, in \u001B[0;36mDataFrame.__getitem__\u001B[0;34m(self, key)\u001B[0m\n\u001B[1;32m 4100\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mcolumns\u001B[38;5;241m.\u001B[39mnlevels \u001B[38;5;241m>\u001B[39m \u001B[38;5;241m1\u001B[39m:\n\u001B[1;32m 4101\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_getitem_multilevel(key)\n\u001B[0;32m-> 4102\u001B[0m indexer \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mcolumns\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mget_loc\u001B[49m\u001B[43m(\u001B[49m\u001B[43mkey\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 4103\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m is_integer(indexer):\n\u001B[1;32m 4104\u001B[0m indexer \u001B[38;5;241m=\u001B[39m [indexer]\n", - "File \u001B[0;32m~/Projects/COMO/.venv/lib/python3.10/site-packages/pandas/core/indexes/base.py:3812\u001B[0m, in \u001B[0;36mIndex.get_loc\u001B[0;34m(self, key)\u001B[0m\n\u001B[1;32m 3807\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(casted_key, \u001B[38;5;28mslice\u001B[39m) \u001B[38;5;129;01mor\u001B[39;00m (\n\u001B[1;32m 3808\u001B[0m \u001B[38;5;28misinstance\u001B[39m(casted_key, abc\u001B[38;5;241m.\u001B[39mIterable)\n\u001B[1;32m 3809\u001B[0m \u001B[38;5;129;01mand\u001B[39;00m \u001B[38;5;28many\u001B[39m(\u001B[38;5;28misinstance\u001B[39m(x, \u001B[38;5;28mslice\u001B[39m) \u001B[38;5;28;01mfor\u001B[39;00m x \u001B[38;5;129;01min\u001B[39;00m casted_key)\n\u001B[1;32m 3810\u001B[0m ):\n\u001B[1;32m 3811\u001B[0m \u001B[38;5;28;01mraise\u001B[39;00m InvalidIndexError(key)\n\u001B[0;32m-> 3812\u001B[0m \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mKeyError\u001B[39;00m(key) \u001B[38;5;28;01mfrom\u001B[39;00m \u001B[38;5;21;01merr\u001B[39;00m\n\u001B[1;32m 3813\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mTypeError\u001B[39;00m:\n\u001B[1;32m 3814\u001B[0m \u001B[38;5;66;03m# If we have a listlike key, _check_indexing_error will raise\u001B[39;00m\n\u001B[1;32m 3815\u001B[0m \u001B[38;5;66;03m# InvalidIndexError. Otherwise we fall through and re-raise\u001B[39;00m\n\u001B[1;32m 3816\u001B[0m \u001B[38;5;66;03m# the TypeError.\u001B[39;00m\n\u001B[1;32m 3817\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_check_indexing_error(key)\n", - "\u001B[0;31mKeyError\u001B[0m: 'ensembl_gene_id'" - ] - } - ], - "execution_count": 15 + ] }, { "cell_type": "markdown", @@ -731,12 +684,14 @@ }, { "cell_type": "code", + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2024-12-16T19:54:26.540397Z", "start_time": "2024-12-16T19:54:26.515554Z" } }, + "outputs": [], "source": [ "from como.merge_xomics import AdjustmentMethod, merge_xomics\n", "\n", @@ -791,30 +746,7 @@ " output_final_model_scores_filepath=Path(f\"data/results/{context}/model_scores_{context}.csv\"),\n", " output_figure_dirpath=Path(f\"data/results/{context}/figures\")\n", " )" - ], - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "data/results/naiveB/total-rna/trna_activity_naiveB.csv\n" - ] - }, - { - "ename": "FileExistsError", - "evalue": "[Errno 17] File exists: 'data/results/naiveB/total-rna'", - "output_type": "error", - "traceback": [ - "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", - "\u001B[0;31mFileExistsError\u001B[0m Traceback (most recent call last)", - "Cell \u001B[0;32mIn[6], line 24\u001B[0m\n\u001B[1;32m 20\u001B[0m trna_batches \u001B[38;5;241m=\u001B[39m {\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mnaiveB\u001B[39m\u001B[38;5;124m\"\u001B[39m: [\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mnaiveB_S3R1\u001B[39m\u001B[38;5;124m\"\u001B[39m, \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mnaiveB_S3R2\u001B[39m\u001B[38;5;124m\"\u001B[39m, \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mnaiveB_S3R3\u001B[39m\u001B[38;5;124m\"\u001B[39m]}\n\u001B[1;32m 23\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m context \u001B[38;5;129;01min\u001B[39;00m context_names:\n\u001B[0;32m---> 24\u001B[0m \u001B[38;5;28;01mawait\u001B[39;00m merge_xomics(\n\u001B[1;32m 25\u001B[0m context_name\u001B[38;5;241m=\u001B[39mcontext_names,\n\u001B[1;32m 26\u001B[0m trna_matrix_or_filepath\u001B[38;5;241m=\u001B[39mtrna_matrix_filepath[context],\n\u001B[1;32m 27\u001B[0m mrna_matrix_or_filepath\u001B[38;5;241m=\u001B[39mmrna_matrix_filepath[context],\n\u001B[1;32m 28\u001B[0m scrna_matrix_or_filepath\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mNone\u001B[39;00m, \u001B[38;5;66;03m# scrna_matrix_filepath[context],\u001B[39;00m\n\u001B[1;32m 29\u001B[0m proteomic_matrix_or_filepath\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mNone\u001B[39;00m, \u001B[38;5;66;03m# proteomics_matrix_filepath[context],\u001B[39;00m\n\u001B[1;32m 30\u001B[0m trna_batches\u001B[38;5;241m=\u001B[39mtrna_batches,\n\u001B[1;32m 31\u001B[0m mrna_batches\u001B[38;5;241m=\u001B[39mmrna_batches,\n\u001B[1;32m 32\u001B[0m scrna_batches\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mNone\u001B[39;00m,\n\u001B[1;32m 33\u001B[0m proteomic_batches\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mNone\u001B[39;00m,\n\u001B[1;32m 34\u001B[0m trna_weight\u001B[38;5;241m=\u001B[39mtotal_rna_weight,\n\u001B[1;32m 35\u001B[0m mrna_weight\u001B[38;5;241m=\u001B[39mmrna_weight,\n\u001B[1;32m 36\u001B[0m scrna_weight\u001B[38;5;241m=\u001B[39msingle_cell_weight,\n\u001B[1;32m 37\u001B[0m proteomic_weight\u001B[38;5;241m=\u001B[39mproteomics_weight,\n\u001B[1;32m 38\u001B[0m minimum_source_expression\u001B[38;5;241m=\u001B[39mminimum_source_expression,\n\u001B[1;32m 39\u001B[0m expression_requirement\u001B[38;5;241m=\u001B[39mexpression_requirement,\n\u001B[1;32m 40\u001B[0m adjust_method\u001B[38;5;241m=\u001B[39mrequirement_adjustment_method,\n\u001B[1;32m 41\u001B[0m force_activate_high_confidence\u001B[38;5;241m=\u001B[39mforce_activate_high_confidence,\n\u001B[1;32m 42\u001B[0m adjust_for_na\u001B[38;5;241m=\u001B[39madjust_for_na_sources,\n\u001B[1;32m 43\u001B[0m merge_zfpkm_distribution\u001B[38;5;241m=\u001B[39mmerge_zfpkm_distrubution,\n\u001B[1;32m 44\u001B[0m keep_transcriptomics_score\u001B[38;5;241m=\u001B[39mkeep_transcriptomics_score,\n\u001B[1;32m 45\u001B[0m output_merge_activity_filepath\u001B[38;5;241m=\u001B[39mPath(\u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mdata/results/\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m/ActiveGenes_\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m_Merged.csv\u001B[39m\u001B[38;5;124m\"\u001B[39m),\n\u001B[1;32m 46\u001B[0m output_transcriptomic_details_filepath\u001B[38;5;241m=\u001B[39mPath(\u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mdata/results/\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m/TranscriptomicDetails_\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m.csv\u001B[39m\u001B[38;5;124m\"\u001B[39m),\n\u001B[1;32m 47\u001B[0m output_trna_activity_filepath\u001B[38;5;241m=\u001B[39mPath(\u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mdata/results/\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m/total-rna/trna_activity_\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m.csv\u001B[39m\u001B[38;5;124m\"\u001B[39m),\n\u001B[1;32m 48\u001B[0m output_mrna_activity_filepath\u001B[38;5;241m=\u001B[39mPath(\u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mdata/results/\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m/mrna/mrna_activity_\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m.csv\u001B[39m\u001B[38;5;124m\"\u001B[39m),\n\u001B[1;32m 49\u001B[0m output_scrna_activity_filepath\u001B[38;5;241m=\u001B[39mPath(\u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mdata/results/\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m/scrna/scrna_activity_\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m.csv\u001B[39m\u001B[38;5;124m\"\u001B[39m),\n\u001B[1;32m 50\u001B[0m output_proteomic_activity_filepath\u001B[38;5;241m=\u001B[39mPath(\u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mdata/results/\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m/proteomics/proteomic_activity_\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m.csv\u001B[39m\u001B[38;5;124m\"\u001B[39m),\n\u001B[1;32m 51\u001B[0m output_final_model_scores_filepath\u001B[38;5;241m=\u001B[39mPath(\u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mdata/results/\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m/model_scores_\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m.csv\u001B[39m\u001B[38;5;124m\"\u001B[39m),\n\u001B[1;32m 52\u001B[0m output_figure_dirpath\u001B[38;5;241m=\u001B[39mPath(\u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mdata/results/\u001B[39m\u001B[38;5;132;01m{\u001B[39;00mcontext\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m/figures\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n\u001B[1;32m 53\u001B[0m )\n", - "File \u001B[0;32m~/Projects/COMO/main/como/merge_xomics.py:678\u001B[0m, in \u001B[0;36mmerge_xomics\u001B[0;34m(context_name, trna_matrix_or_filepath, mrna_matrix_or_filepath, scrna_matrix_or_filepath, proteomic_matrix_or_filepath, trna_batches, mrna_batches, scrna_batches, proteomic_batches, output_merge_activity_filepath, output_transcriptomic_details_filepath, output_trna_activity_filepath, output_mrna_activity_filepath, output_scrna_activity_filepath, output_proteomic_activity_filepath, output_final_model_scores_filepath, output_figure_dirpath, trna_weight, mrna_weight, scrna_weight, proteomic_weight, minimum_source_expression, expression_requirement, adjust_method, force_activate_high_confidence, adjust_for_na, merge_zfpkm_distribution, keep_transcriptomics_score, weighted_z_floor, weighted_z_ceiling)\u001B[0m\n\u001B[1;32m 676\u001B[0m output_transcriptomic_details_filepath\u001B[38;5;241m.\u001B[39mparent\u001B[38;5;241m.\u001B[39mmkdir(parents\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mTrue\u001B[39;00m)\n\u001B[1;32m 677\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m output_trna_activity_filepath \u001B[38;5;129;01mand\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m output_trna_activity_filepath\u001B[38;5;241m.\u001B[39mexists():\n\u001B[0;32m--> 678\u001B[0m \u001B[43moutput_trna_activity_filepath\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mparent\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mmkdir\u001B[49m\u001B[43m(\u001B[49m\u001B[43mparents\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;28;43;01mTrue\u001B[39;49;00m\u001B[43m)\u001B[49m\n\u001B[1;32m 679\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m output_mrna_activity_filepath \u001B[38;5;129;01mand\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m output_mrna_activity_filepath\u001B[38;5;241m.\u001B[39mexists():\n\u001B[1;32m 680\u001B[0m output_mrna_activity_filepath\u001B[38;5;241m.\u001B[39mparent\u001B[38;5;241m.\u001B[39mmkdir(parents\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mTrue\u001B[39;00m)\n", - "File \u001B[0;32m~/.local/share/uv/python/cpython-3.10.15-macos-aarch64-none/lib/python3.10/pathlib.py:1175\u001B[0m, in \u001B[0;36mPath.mkdir\u001B[0;34m(self, mode, parents, exist_ok)\u001B[0m\n\u001B[1;32m 1171\u001B[0m \u001B[38;5;250m\u001B[39m\u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[1;32m 1172\u001B[0m \u001B[38;5;124;03mCreate a new directory at this given path.\u001B[39;00m\n\u001B[1;32m 1173\u001B[0m \u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[1;32m 1174\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[0;32m-> 1175\u001B[0m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_accessor\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mmkdir\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mmode\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m 1176\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mFileNotFoundError\u001B[39;00m:\n\u001B[1;32m 1177\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m parents \u001B[38;5;129;01mor\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mparent \u001B[38;5;241m==\u001B[39m \u001B[38;5;28mself\u001B[39m:\n", - "\u001B[0;31mFileExistsError\u001B[0m: [Errno 17] File exists: 'data/results/naiveB/total-rna'" - ] - } - ], - "execution_count": 6 + ] }, { "cell_type": "markdown", From 35a0bf239a6b88c651fb2c8fc186ddbc20d28c17 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 31 Jan 2025 13:44:55 -0600 Subject: [PATCH 197/265] fix: rename column names --- main/como/create_context_specific_model.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index eb5796fc..1860745e 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -508,7 +508,7 @@ async def _collect_boundary_reactions(path: Path) -> _BoundaryReactions: df: pd.DataFrame = await _create_df(path) for column in df.columns: if column not in [ - "boundary", + "reaction", "abbreviation", "compartment", "minimum reaction rate", @@ -524,7 +524,7 @@ async def _collect_boundary_reactions(path: Path) -> _BoundaryReactions: ) reactions: list[str] = [""] * len(df) - boundary_type: list[str] = df["boundary"].tolist() + boundary_type: list[str] = df["reaction"].tolist() reaction_abbreviation: list[str] = df["abbreviation"].astype(str).tolist() reaction_compartment: list[str] = df["compartment"].astype(str).tolist() boundary_map = {"exchange": "EX", "demand": "DM", "sink": "SK"} From 13f325393c8778d330659663e9fe12e3cb169038 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 3 Jun 2025 16:09:45 -0500 Subject: [PATCH 198/265] chore: increase line length Signed-off-by: Josh Loecker --- ruff.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruff.toml b/ruff.toml index eeea6f84..309140fa 100644 --- a/ruff.toml +++ b/ruff.toml @@ -1,4 +1,4 @@ -line-length = 120 +line-length = 150 extend-include = ["docs/**/*.py", "tests/**/*.py", "**/*.ipynb"] [format] From 12aa4ad6d9aaf2c4e3c88130c5d41f921b5eb3a5 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 3 Jun 2025 16:11:28 -0500 Subject: [PATCH 199/265] refactor: updated to be more python-like Signed-off-by: Josh Loecker --- main/COMO.ipynb | 208 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 161 insertions(+), 47 deletions(-) diff --git a/main/COMO.ipynb b/main/COMO.ipynb index f86b9bd1..6c2b24fb 100644 --- a/main/COMO.ipynb +++ b/main/COMO.ipynb @@ -2,11 +2,7 @@ "cells": [ { "cell_type": "markdown", - "metadata": { - "jupyter": { - "source_hidden": true - } - }, + "metadata": {}, "source": [ "# COMO: Constraint-based Optomization of Metabolic Objectives\n", "\n", @@ -60,11 +56,7 @@ }, { "cell_type": "markdown", - "metadata": { - "jupyter": { - "source_hidden": true - } - }, + "metadata": {}, "source": [ "# Step 1: Data Preprocessing and Analysis\n", "\n", @@ -233,14 +225,42 @@ }, { "cell_type": "code", - "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2024-12-16T20:09:29.761117Z", - "start_time": "2024-12-16T20:09:29.754605Z" + "end_time": "2025-05-14T22:26:41.582304Z", + "start_time": "2025-05-14T22:26:41.578323Z" } }, + "source": [ + "from pathlib import Path\n", + "\n", + "\n", + "def get_notebook_dir() -> Path:\n", + " \"\"\"Get the directory of the COMO.ipynb notebook.\n", + "\n", + " This is used to set the proper input and output paths for the rest of the notebook\n", + " \"\"\"\n", + " current_dir = Path().cwd()\n", + "\n", + " while True:\n", + " files = [i.name for i in current_dir.iterdir()]\n", + " if \"COMO.ipynb\" in files:\n", + " return current_dir\n", + " if current_dir.as_posix() == \"/\":\n", + " raise FileNotFoundError(\"Root directory could not be determined; unable to find 'COMO.ipynb'\")\n", + " current_dir = current_dir.parent" + ], "outputs": [], + "execution_count": 1 + }, + { + "cell_type": "code", + "metadata": { + "ExecuteTime": { + "end_time": "2025-05-14T22:38:52.351270Z", + "start_time": "2025-05-14T22:38:52.343987Z" + } + }, "source": [ "from pathlib import Path\n", "\n", @@ -248,26 +268,37 @@ "from como.rnaseq_preprocess import rnaseq_preprocess\n", "\n", "taxon_id = 9606\n", - "context_names = [\"naiveB\"]\n", + "# context_names = [\"control1hr\", \"control6hr\", \"control15min\", \"control24hr\", \"indralin1hr\", \"indralin6hr\",\n", + "# \"indralin15min\", \"indralin24hr\", \"notreatment\"]\n", + "context_names = [\"notreatment\"]\n", + "notebook_dir = get_notebook_dir()\n", "\n", "# Input Components\n", - "como_context_dir = {context: Path(f\"data/COMO_input/{context}\") for context in context_names}\n", - "gene_info_filepath = {context: Path(f\"data/results/{context}/gene_info.csv\") for context in context_names}\n", - "trna_matrix_filepath = {context: Path(f\"data/results/{context}/total-rna/totalrna_{context}.csv\") for context in context_names}\n", - "mrna_matrix_filepath = {context: Path(f\"data/results/{context}/mrna/mrna_{context}.csv\") for context in context_names}\n", - "proteomics_matrix_filepath = {context: Path(f\"data/data_matrices/{context}/protein_abundance_{context}.csv\") for context in context_names}\n", + "como_context_dir = {context: Path(notebook_dir / f\"data/COMO_input/{context}\") for context in context_names}\n", + "gene_info_filepath = {context: Path(notebook_dir / f\"data/results/{context}/gene_info.csv\") for context in\n", + " context_names}\n", + "trna_matrix_filepath = {context: Path(notebook_dir / f\"data/results/{context}/total-rna/totalrna_{context}.csv\") for\n", + " context in\n", + " context_names}\n", + "mrna_matrix_filepath = {context: Path(notebook_dir / f\"data/results/{context}/mrna/mrna_{context}.csv\") for context in\n", + " context_names}\n", + "proteomics_matrix_filepath = {\n", + " context: Path(notebook_dir / f\"data/data_matrices/{context}/protein_abundance_{context}.csv\") for context\n", + " in context_names}\n", "\n", "# No single-cell data is provided by default; COMO accepts single-cell data in CSV or h5ad format\n", "# If you are using single-cell data, adjust the following lines accordingly\n", - "scrna_matrix_filepath = {context: Path(f\"data/results/{context}/scrna/scrna_{context}.csv\") for context in context_names}\n", + "scrna_matrix_filepath = {context: Path(notebook_dir / f\"data/results/{context}/scrna/scrna_{context}.csv\") for context\n", + " in\n", + " context_names}\n", "# scrna_matrix_filepath = [Path(f\"data/results/{context}/scrna/scrna_{context}.h5ad\") for context in context_names]\n", "\n", - "trna_metadata_filepath = Path(\"data/config_sheets/trna_config.xlsx\")\n", - "mrna_metadata_filepath = Path(\"data/config_sheets/mrna_config.xlsx\")\n", - "proteomics_metadata_filepath = Path(\"data/config_sheets/proteomics_config.xlsx\")\n", - "\n", - "# Output Components\n" - ] + "trna_metadata_filepath = Path(notebook_dir / \"data/config_sheets/trna_config.xlsx\")\n", + "mrna_metadata_filepath = Path(notebook_dir / \"data/config_sheets/mrna_config.xlsx\")\n", + "proteomics_metadata_filepath = Path(notebook_dir / \"data/config_sheets/proteomics_config.xlsx\")\n" + ], + "outputs": [], + "execution_count": 4 }, { "cell_type": "markdown", @@ -282,14 +313,14 @@ }, { "cell_type": "code", - "execution_count": null, "metadata": { + "jupyter": { + "is_executing": true + }, "ExecuteTime": { - "end_time": "2024-12-16T20:07:08.331063Z", - "start_time": "2024-12-16T20:06:10.188429Z" + "start_time": "2025-05-14T22:39:41.777900Z" } }, - "outputs": [], "source": [ "for context in context_names:\n", " if context not in {*trna_matrix_filepath, *mrna_matrix_filepath}:\n", @@ -302,12 +333,32 @@ " output_gene_info_filepath=gene_info_filepath[context],\n", " output_trna_metadata_filepath=trna_metadata_filepath,\n", " output_trna_count_matrix_filepath=trna_matrix_filepath[context],\n", - " output_mrna_metadata_filepath=mrna_metadata_filepath,\n", - " output_mrna_count_matrix_filepath=mrna_matrix_filepath[context],\n", + " # output_mrna_metadata_filepath=mrna_metadata_filepath,\n", + " # output_mrna_count_matrix_filepath=mrna_matrix_filepath[context],\n", " cache=True,\n", " log_level=\"INFO\",\n", " )" - ] + ], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "notreatment\n", + "9606\n", + "/Users/joshl/Projects/COMO/main/data/COMO_input/notreatment\n", + "None\n", + "/Users/joshl/Projects/COMO/main/data/results/notreatment/gene_info.csv\n", + "/Users/joshl/Projects/COMO/main/data/config_sheets/trna_config.xlsx\n", + "/Users/joshl/Projects/COMO/main/data/results/notreatment/total-rna/totalrna_notreatment.csv\n", + "/Users/joshl/Projects/COMO/main/data/config_sheets/mrna_config.xlsx\n", + "/Users/joshl/Projects/COMO/main/data/results/notreatment/mrna/mrna_notreatment.csv\n", + "True\n", + "INFO\n" + ] + } + ], + "execution_count": null }, { "cell_type": "markdown", @@ -381,14 +432,12 @@ }, { "cell_type": "code", - "execution_count": null, "metadata": { "ExecuteTime": { - "end_time": "2024-12-16T20:08:00.274368Z", - "start_time": "2024-12-16T20:07:48.637980Z" + "end_time": "2025-05-14T22:26:45.087604Z", + "start_time": "2025-05-14T22:26:44.394120Z" } }, - "outputs": [], "source": [ "from como.rnaseq_gen import FilteringTechnique, rnaseq_gen\n", "\n", @@ -399,10 +448,10 @@ "technique = FilteringTechnique.ZFPKM\n", "cutoff = -3\n", "\n", - "\n", "for context in context_names:\n", " if context not in trna_matrix_filepath:\n", " continue\n", + " output_zscore_norm_filepath = Path(get_notebook_dir() / f\"data/results/{context}/z_score_normalization.csv\")\n", " await rnaseq_gen(\n", " context_name=context,\n", " input_rnaseq_filepath=trna_matrix_filepath[context],\n", @@ -410,15 +459,84 @@ " output_boolean_activity_filepath=trna_matrix_filepath[context],\n", " prep=RNAType.TRNA,\n", " taxon_id=taxon_id,\n", - " input_metadata_filepath=trna_metadata_filepath,\n", + " input_metadata_filepath_or_df=trna_metadata_filepath,\n", " replicate_ratio=replicate_ratio,\n", " high_replicate_ratio=high_confidence_replicate_ratio,\n", " batch_ratio=batch_ratio,\n", " high_batch_ratio=high_confidence_batch_ratio,\n", " technique=technique,\n", - " cutoff=cutoff\n", + " cutoff=cutoff,\n", + " output_zscore_normalization_filepath=output_zscore_norm_filepath,\n", " )" - ] + ], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " ensembl_gene_id control1hr_S1R1 control1hr_S1R2 control1hr_S2R1 \\\n", + "0 ENSMUSG00000000001 1377.0 1373.0 1388.0 \n", + "1 ENSMUSG00000000003 0.0 0.0 0.0 \n", + "2 ENSMUSG00000000028 551.0 552.0 464.0 \n", + "3 ENSMUSG00000000031 1.0 5.0 1.0 \n", + "4 ENSMUSG00000000037 21.0 9.0 24.0 \n", + "... ... ... ... ... \n", + "77343 ENSMUSG00002076988 0.0 0.0 0.0 \n", + "77344 ENSMUSG00002076989 0.0 0.0 0.0 \n", + "77345 ENSMUSG00002076990 0.0 0.0 0.0 \n", + "77346 ENSMUSG00002076991 0.0 0.0 0.0 \n", + "77347 ENSMUSG00002076992 0.0 0.0 0.0 \n", + "\n", + " control1hr_S2R2 control1hr_S3R1 control1hr_S3R2 control1hr_S4R1 \\\n", + "0 1393.0 1527 1476.0 1552 \n", + "1 0.0 0 0.0 0 \n", + "2 537.0 656 653.0 677 \n", + "3 1.0 0 0.0 0 \n", + "4 18.0 28 19.0 33 \n", + "... ... ... ... ... \n", + "77343 0.0 0 0.0 0 \n", + "77344 0.0 0 0.0 0 \n", + "77345 0.0 0 0.0 0 \n", + "77346 0.0 0 0.0 0 \n", + "77347 0.0 0 0.0 0 \n", + "\n", + " control1hr_S4R2 \n", + "0 1676 \n", + "1 0 \n", + "2 656 \n", + "3 0 \n", + "4 37 \n", + "... ... \n", + "77343 0 \n", + "77344 0 \n", + "77345 0 \n", + "77346 0 \n", + "77347 0 \n", + "\n", + "[77348 rows x 9 columns]\n" + ] + }, + { + "ename": "KeyError", + "evalue": "'entrez_gene_id'", + "output_type": "error", + "traceback": [ + "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m", + "\u001B[0;31mKeyError\u001B[0m Traceback (most recent call last)", + "\u001B[0;32m/var/folders/6s/9l9z74v90tn8lprrp7fchb9w0000gn/T/ipykernel_84074/4036172948.py\u001B[0m in \u001B[0;36m?\u001B[0;34m()\u001B[0m\n\u001B[1;32m 10\u001B[0m \u001B[0;32mfor\u001B[0m \u001B[0mcontext\u001B[0m \u001B[0;32min\u001B[0m \u001B[0mcontext_names\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 11\u001B[0m \u001B[0;32mif\u001B[0m \u001B[0mcontext\u001B[0m \u001B[0;32mnot\u001B[0m \u001B[0;32min\u001B[0m \u001B[0mtrna_matrix_filepath\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 12\u001B[0m \u001B[0;32mcontinue\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 13\u001B[0m \u001B[0moutput_zscore_norm_filepath\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mPath\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mget_notebook_dir\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m)\u001B[0m \u001B[0;34m/\u001B[0m \u001B[0;34mf\"\u001B[0m\u001B[0;34mdata/results/\u001B[0m\u001B[0;34m{\u001B[0m\u001B[0mcontext\u001B[0m\u001B[0;34m}\u001B[0m\u001B[0;34m/z_score_normalization.csv\u001B[0m\u001B[0;34m\"\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m---> 14\u001B[0;31m await rnaseq_gen(\n\u001B[0m\u001B[1;32m 15\u001B[0m \u001B[0mcontext_name\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mcontext\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 16\u001B[0m \u001B[0minput_rnaseq_filepath\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mtrna_matrix_filepath\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0mcontext\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 17\u001B[0m \u001B[0minput_gene_info_filepath\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mgene_info_filepath\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0mcontext\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/Projects/COMO/main/como/rnaseq_gen.py\u001B[0m in \u001B[0;36m?\u001B[0;34m(context_name, input_rnaseq_filepath, input_gene_info_filepath, prep, taxon_id, output_boolean_activity_filepath, output_zscore_normalization_filepath, input_metadata_filepath_or_df, replicate_ratio, high_replicate_ratio, batch_ratio, high_batch_ratio, technique, zfpkm_peak_height, zfpkm_peak_distance, zfpkm_bandwidth, cutoff, force_zfpkm_plot, log_level, log_location, output_zfpkm_png_filepath)\u001B[0m\n\u001B[1;32m 933\u001B[0m \u001B[0mlevel\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mLogLevel\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mERROR\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 934\u001B[0m \u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 935\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 936\u001B[0m \u001B[0mlogger\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mdebug\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34mf\"\u001B[0m\u001B[0;34mStarting '\u001B[0m\u001B[0;34m{\u001B[0m\u001B[0mcontext_name\u001B[0m\u001B[0;34m}\u001B[0m\u001B[0;34m'\u001B[0m\u001B[0;34m\"\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 937\u001B[0;31m await _process(\n\u001B[0m\u001B[1;32m 938\u001B[0m \u001B[0mcontext_name\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mcontext_name\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 939\u001B[0m \u001B[0mrnaseq_matrix_filepath\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0minput_rnaseq_filepath\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 940\u001B[0m \u001B[0mmetadata_df\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mmetadata_df\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/Projects/COMO/main/como/rnaseq_gen.py\u001B[0m in \u001B[0;36m?\u001B[0;34m(context_name, rnaseq_matrix_filepath, metadata_df, gene_info_df, prep, taxon, replicate_ratio, batch_ratio, high_replicate_ratio, high_batch_ratio, technique, cut_off, force_zfpkm_plot, peak_parameters, bandwidth, output_boolean_activity_filepath, output_zscore_normalization_filepath, output_zfpkm_png_filepath)\u001B[0m\n\u001B[1;32m 723\u001B[0m \u001B[0mhigh_replicate_ratio\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mhigh_replicate_ratio\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 724\u001B[0m \u001B[0mhigh_batch_ratio\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mhigh_batch_ratio\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 725\u001B[0m \u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 726\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 727\u001B[0;31m read_counts_results: _ReadMatrixResults = await _build_matrix_results(\n\u001B[0m\u001B[1;32m 728\u001B[0m \u001B[0mmatrix\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mrnaseq_matrix\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 729\u001B[0m \u001B[0mgene_info\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mgene_info_df\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 730\u001B[0m \u001B[0mmetadata_df\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mmetadata_df\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/Projects/COMO/main/como/rnaseq_gen.py\u001B[0m in \u001B[0;36m?\u001B[0;34m(matrix, gene_info, metadata_df, taxon)\u001B[0m\n\u001B[1;32m 169\u001B[0m \u001B[0mconversion\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0;34m\"ensembl_gene_id\"\u001B[0m\u001B[0;34m]\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mconversion\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0;34m\"ensembl_gene_id\"\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mstr\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0msplit\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m\",\"\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 170\u001B[0m \u001B[0mconversion\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mconversion\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mexplode\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m\"ensembl_gene_id\"\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 171\u001B[0m \u001B[0mconversion\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mreset_index\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0minplace\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0;32mTrue\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mdrop\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0;32mTrue\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 172\u001B[0m \u001B[0;31m# print(conversion)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 173\u001B[0;31m \u001B[0mmatrix\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mmatrix\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mmerge\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mconversion\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mon\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0;34m\"ensembl_gene_id\"\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0;34m\"entrez_gene_id\"\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0;34m\"gene_symbol\"\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mhow\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0;34m\"left\"\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 174\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 175\u001B[0m \u001B[0;31m# Only include Entrez and Ensembl Gene IDs that are present in `gene_info`\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 176\u001B[0m \u001B[0mmatrix\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0;34m\"entrez_gene_id\"\u001B[0m\u001B[0;34m]\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mmatrix\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0;34m\"entrez_gene_id\"\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mstr\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0msplit\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m\"//\"\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/Projects/COMO/.venv/lib/python3.12/site-packages/pandas/core/frame.py\u001B[0m in \u001B[0;36m?\u001B[0;34m(self, right, how, on, left_on, right_on, left_index, right_index, sort, suffixes, copy, indicator, validate)\u001B[0m\n\u001B[1;32m 10828\u001B[0m \u001B[0mvalidate\u001B[0m\u001B[0;34m:\u001B[0m \u001B[0mMergeValidate\u001B[0m \u001B[0;34m|\u001B[0m \u001B[0;32mNone\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0;32mNone\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 10829\u001B[0m \u001B[0;34m)\u001B[0m \u001B[0;34m->\u001B[0m \u001B[0mDataFrame\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 10830\u001B[0m \u001B[0;32mfrom\u001B[0m \u001B[0mpandas\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mcore\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mreshape\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mmerge\u001B[0m \u001B[0;32mimport\u001B[0m \u001B[0mmerge\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 10831\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m> 10832\u001B[0;31m return merge(\n\u001B[0m\u001B[1;32m 10833\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 10834\u001B[0m \u001B[0mright\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 10835\u001B[0m \u001B[0mhow\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mhow\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/Projects/COMO/.venv/lib/python3.12/site-packages/pandas/core/reshape/merge.py\u001B[0m in \u001B[0;36m?\u001B[0;34m(left, right, how, on, left_on, right_on, left_index, right_index, sort, suffixes, copy, indicator, validate)\u001B[0m\n\u001B[1;32m 166\u001B[0m \u001B[0mvalidate\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mvalidate\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 167\u001B[0m \u001B[0mcopy\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mcopy\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 168\u001B[0m \u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 169\u001B[0m \u001B[0;32melse\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 170\u001B[0;31m op = _MergeOperation(\n\u001B[0m\u001B[1;32m 171\u001B[0m \u001B[0mleft_df\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 172\u001B[0m \u001B[0mright_df\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 173\u001B[0m \u001B[0mhow\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mhow\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/Projects/COMO/.venv/lib/python3.12/site-packages/pandas/core/reshape/merge.py\u001B[0m in \u001B[0;36m?\u001B[0;34m(self, left, right, how, on, left_on, right_on, left_index, right_index, sort, suffixes, indicator, validate)\u001B[0m\n\u001B[1;32m 790\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mright_join_keys\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 791\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mjoin_names\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 792\u001B[0m \u001B[0mleft_drop\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 793\u001B[0m \u001B[0mright_drop\u001B[0m\u001B[0;34m,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m--> 794\u001B[0;31m \u001B[0;34m)\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0m_get_merge_keys\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 795\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 796\u001B[0m \u001B[0;32mif\u001B[0m \u001B[0mleft_drop\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 797\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mleft\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mleft\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0m_drop_labels_or_levels\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mleft_drop\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/Projects/COMO/.venv/lib/python3.12/site-packages/pandas/core/reshape/merge.py\u001B[0m in \u001B[0;36m?\u001B[0;34m(self)\u001B[0m\n\u001B[1;32m 1306\u001B[0m \u001B[0;32mif\u001B[0m \u001B[0mlk\u001B[0m \u001B[0;32mis\u001B[0m \u001B[0;32mnot\u001B[0m \u001B[0;32mNone\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 1307\u001B[0m \u001B[0;31m# Then we're either Hashable or a wrong-length arraylike,\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 1308\u001B[0m \u001B[0;31m# the latter of which will raise\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 1309\u001B[0m \u001B[0mlk\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mcast\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mHashable\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0mlk\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m-> 1310\u001B[0;31m \u001B[0mleft_keys\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mappend\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mleft\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0m_get_label_or_level_values\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mlk\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 1311\u001B[0m \u001B[0mjoin_names\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mappend\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mlk\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 1312\u001B[0m \u001B[0;32melse\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 1313\u001B[0m \u001B[0;31m# work-around for merge_asof(left_index=True)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;32m~/Projects/COMO/.venv/lib/python3.12/site-packages/pandas/core/generic.py\u001B[0m in \u001B[0;36m?\u001B[0;34m(self, key, axis)\u001B[0m\n\u001B[1;32m 1907\u001B[0m \u001B[0mvalues\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mxs\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mkey\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0maxis\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0mother_axes\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0;36m0\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0m_values\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 1908\u001B[0m \u001B[0;32melif\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0m_is_level_reference\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mkey\u001B[0m\u001B[0;34m,\u001B[0m \u001B[0maxis\u001B[0m\u001B[0;34m=\u001B[0m\u001B[0maxis\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 1909\u001B[0m \u001B[0mvalues\u001B[0m \u001B[0;34m=\u001B[0m \u001B[0mself\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0maxes\u001B[0m\u001B[0;34m[\u001B[0m\u001B[0maxis\u001B[0m\u001B[0;34m]\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mget_level_values\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mkey\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0m_values\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 1910\u001B[0m \u001B[0;32melse\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0;32m-> 1911\u001B[0;31m \u001B[0;32mraise\u001B[0m \u001B[0mKeyError\u001B[0m\u001B[0;34m(\u001B[0m\u001B[0mkey\u001B[0m\u001B[0;34m)\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[0m\u001B[1;32m 1912\u001B[0m \u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 1913\u001B[0m \u001B[0;31m# Check for duplicates\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n\u001B[1;32m 1914\u001B[0m \u001B[0;32mif\u001B[0m \u001B[0mvalues\u001B[0m\u001B[0;34m.\u001B[0m\u001B[0mndim\u001B[0m \u001B[0;34m>\u001B[0m \u001B[0;36m1\u001B[0m\u001B[0;34m:\u001B[0m\u001B[0;34m\u001B[0m\u001B[0;34m\u001B[0m\u001B[0m\n", + "\u001B[0;31mKeyError\u001B[0m: 'entrez_gene_id'" + ] + } + ], + "execution_count": 3 }, { "cell_type": "markdown", @@ -707,14 +825,12 @@ "merge_zfpkm_distrubution = True\n", "keep_transcriptomics_score = True\n", "\n", - "\n", "mrna_batches = {\"naiveB\": [\n", " \"naiveB_S1R1\", \"naiveB_S1R2\", \"naiveB_S1R3\", \"naiveB_S1R4\",\n", " \"naiveB_S2R1\", \"naiveB_S2R2\", \"naiveB_S2R3\", \"naiveB_S2R4\",\n", "]}\n", "trna_batches = {\"naiveB\": [\"naiveB_S3R1\", \"naiveB_S3R2\", \"naiveB_S3R3\"]}\n", "\n", - "\n", "for context in context_names:\n", " await merge_xomics(\n", " context_name=context,\n", @@ -1011,7 +1127,6 @@ "data_source = \"rnaseq\"\n", "taxon_id = \"human\"\n", "\n", - "\n", "for context_name in stringlist_to_list(context_names):\n", " disease_config_file = f\"disease_data_inputs_{context_name}.xlsx\"\n", "\n", @@ -1083,7 +1198,6 @@ "}\n", "sovler = \"gurobi\"\n", "\n", - "\n", "config = Config()\n", "\n", "drug_raw_file = \"Repurposing_Hub_export.txt\"\n", @@ -1111,7 +1225,7 @@ " tissue_specific_model_filepath = model_files[context]\n", " else:\n", " tissue_specific_model_filepath = (\n", - " config.data_dir / \"results\" / context / f\"{context}_SpecificModel_{recon_algorithm}.mat\"\n", + " config.data_dir / \"results\" / context / f\"{context}_SpecificModel_{recon_algorithm}.mat\"\n", " )\n", "\n", " # fmt: off\n", @@ -1152,7 +1266,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.15" + "version": "3.12.6" }, "toc-autonumbering": true, "toc-showcode": true From a3c4b2883c1bed8d51c15533a1ad7e80dba1e7d1 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 3 Jun 2025 16:12:48 -0500 Subject: [PATCH 200/265] style: ruff formatting; error handling Signed-off-by: Josh Loecker --- main/como/utils.py | 47 +++++++++++++++++++--------------------------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/main/como/utils.py b/main/como/utils.py index 22652f6a..fc8c9739 100644 --- a/main/como/utils.py +++ b/main/como/utils.py @@ -47,20 +47,14 @@ def stringlist_to_list(stringlist: str | list[str]) -> list[str]: new_list: list[str] = stringlist.strip("[]").replace("'", "").replace(" ", "").split(",") # Show a warning if more than one item is present in the list (this means we are using the old method) - logger.critical( - "DeprecationWarning: Please use the new method of providing context names, " - "i.e. --output-filetypes 'type1 type2 type3'." - ) + logger.critical("DeprecationWarning: Please use the new method of providing context names, i.e. --output-filetypes 'type1 type2 type3'.") logger.critical( "If you are using COMO, this can be done by setting the 'context_names' variable to a " "simple string separated by spaces. Here are a few examples!" ) logger.critical("context_names = 'cellType1 cellType2 cellType3'") logger.critical("output_filetypes = 'output1 output2 output3'") - logger.critical( - "\nYour current method of passing context names will be removed in the future. " - "Update your variables above accordingly!\n\n" - ) + logger.critical("\nYour current method of passing context names will be removed in the future. Update your variables above accordingly!\n\n") return new_list @@ -84,9 +78,9 @@ def split_gene_expression_data( expression_data = expression_data[["entrez_gene_id", "active"]] single_gene_names = expression_data[~expression_data["entrez_gene_id"].astype(str).str.contains("//")] multiple_gene_names = expression_data[expression_data["entrez_gene_id"].astype(str).str.contains("//")] - split_gene_names = multiple_gene_names.assign( - entrez_gene_id=multiple_gene_names["entrez_gene_id"].astype(str).str.split("///") - ).explode("entrez_gene_id") + split_gene_names = multiple_gene_names.assign(entrez_gene_id=multiple_gene_names["entrez_gene_id"].astype(str).str.split("///")).explode( + "entrez_gene_id" + ) gene_expressions = pd.concat([single_gene_names, split_gene_names], axis=0, ignore_index=True) if entrez_as_index: @@ -120,9 +114,7 @@ async def _format_determination( :return: A pandas DataFrame """ requested_output = [requested_output] if isinstance(requested_output, Output) else requested_output - coercion = (await biodbnet.db_find(values=input_values, output_db=requested_output, taxon=taxon)).drop( - columns=["Input Type"] - ) + coercion = (await biodbnet.db_find(values=input_values, output_db=requested_output, taxon=taxon)).drop(columns=["Input Type"]) coercion.columns = pd.Index(["input_value", *[o.value.replace(" ", "_").lower() for o in requested_output]]) return coercion @@ -147,16 +139,16 @@ async def _read_file( return None if isinstance(path, Path) and not path.exists(): - logger.critical(f"File {path} does not exist") - raise FileNotFoundError(f"File {path} does not exist") + _log_and_raise_error(f"File {path} does not exist", error=FileNotFoundError, level=LogLevel.CRITICAL) # StringIO is used if a CSV file is read using open() directly if isinstance(path, io.StringIO): return pd.read_csv(path, **kwargs) match path.suffix: - case ".csv" | ".tsv": - kwargs.setdefault("sep", "," if path.suffix == ".csv" else "\t") + case ".csv" | ".tsv" | ".txt": + if "sep" not in kwargs: + kwargs.setdefault("sep", "," if path.suffix == ".csv" else "\t") with path.open("r") as i_stream: content = i_stream.read() return pd.read_csv(io.StringIO(content), **kwargs) @@ -171,13 +163,12 @@ async def _read_file( return df return adata case _: - logger.critical( - f"Unknown file extension '{path.suffix}'. Valid options are '.tsv', '.csv', '.xlsx', '.xls', or '.h5ad'" - ) - raise ValueError( - f"Unknown file extension '{path.suffix}'. " - f"Valid options are '.tsv', '.csv', '.xlsx', '.xls', or '.h5ad'." + _log_and_raise_error( + f"Unknown file extension '{path.suffix}'. Valid options are '.tsv', '.csv', '.xlsx', '.xls', or '.h5ad'", + error=ValueError, + level=LogLevel.CRITICAL, ) + return None async def get_missing_gene_data(values: list[str] | pd.DataFrame, taxon_id: int | str | Taxon) -> pd.DataFrame: @@ -202,9 +193,7 @@ async def get_missing_gene_data(values: list[str] | pd.DataFrame, taxon_id: int return await get_missing_gene_data(values["ensembl_gene_id"].tolist(), taxon_id=taxon_id) else: logger.critical("Unable to find 'gene_symbol', 'entrez_gene_id', or 'ensembl_gene_id' in the input matrix.") - raise ValueError( - "Unable to find 'gene_symbol', 'entrez_gene_id', or 'ensembl_gene_id' in the input matrix." - ) + raise ValueError("Unable to find 'gene_symbol', 'entrez_gene_id', or 'ensembl_gene_id' in the input matrix.") def _listify(value): @@ -225,10 +214,12 @@ def return_placeholder_data() -> pd.DataFrame: def _set_up_logging( - level: LogLevel, + level: LogLevel | str, location: str | TextIOWrapper, formatting: str = LOG_FORMAT, ): + if isinstance(level, str): + level = LogLevel[level.upper()] with contextlib.suppress(ValueError): logger.remove(0) logger.add(sink=location, level=level.value, format=formatting) From c0f5f00c5abe531eeef412c6574d2856dda33caf Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 3 Jun 2025 16:17:04 -0500 Subject: [PATCH 201/265] refactor: remove unwrapping aio file reading for better consistency/reproducibility Signed-off-by: Josh Loecker --- main/como/rnaseq_preprocess.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index 40e8a01d..6375e06a 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -4,12 +4,13 @@ import json import re import sys -from dataclasses import dataclass, field +from dataclasses import asdict, dataclass, field from io import StringIO, TextIOWrapper from itertools import chain from pathlib import Path -from typing import Literal +from typing import Final, Literal +import aiofiles import numpy as np import pandas as pd from fast_bioservices.biothings.mygene import MyGene @@ -41,16 +42,18 @@ async def build_from_tab(cls, filepath: Path) -> _STARinformation: error=ValueError, level=LogLevel.ERROR, ) + if not filepath.exists(): + _log_and_raise_error( + f"Unable to find the .tab file '{filepath}'", + error=FileNotFoundError, + level=LogLevel.ERROR, + ) with filepath.open("r") as i_stream: - unmapped, multimapping, no_feature, ambiguous = await asyncio.gather( - *[ - asyncio.to_thread(i_stream.readline), - asyncio.to_thread(i_stream.readline), - asyncio.to_thread(i_stream.readline), - asyncio.to_thread(i_stream.readline), - ] - ) + unmapped = i_stream.readline() + multimapping = i_stream.readline() + no_feature = i_stream.readline() + ambiguous = i_stream.readline() num_unmapped = [int(i) for i in unmapped.rstrip("\n").split("\t")[1:]] num_multimapping = [int(i) for i in multimapping.rstrip("\n").split("\t")[1:]] From f1a41370fa906825438060572a678eb126fbc294 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 3 Jun 2025 16:19:42 -0500 Subject: [PATCH 202/265] feat: add dataclasses to handle types more easily Signed-off-by: Josh Loecker --- main/como/rnaseq_preprocess.py | 473 ++++++++++++++++++++------------- 1 file changed, 281 insertions(+), 192 deletions(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index 6375e06a..e4c7c416 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -141,10 +141,41 @@ def __post_init__(self): self.__sample_names.sort() +@dataclass(slots=True) +class SampleConfiguration: + sample_name: str + fragment_length: float + layout: str + strand: str + study: str + library_prep: str + + +async def _read_text(path: Path | None, *, default: str, lower: bool = False) -> str: + if path is None: + return default + async with aiofiles.open(path) as f: + txt = (await f.read()).strip() + return txt.lower() if lower else txt + + def _sample_name_from_filepath(file: Path) -> str: return re.search(r".+_S\d+R\d+", file.stem).group() +def _require_one(paths: list[Path], kind: Literal["layout", "strand", "preparation", "fragment"], label: str) -> Path | None: + if len(paths) == 1: + return paths[0] + if len(paths) == 0: + return None + _log_and_raise_error( + f"Multiple matching {kind} files for {label}, make sure there is only one copy for each replicate in COMO_input", + error=ValueError, + level=LogLevel.ERROR, + ) + return None # explicit return None to satisfy type-check + + def _organize_gene_counts_files(data_dir: Path) -> list[_StudyMetrics]: gene_count_dir = Path(data_dir, "geneCounts") strand_dir = Path(data_dir, "strandedness") @@ -156,7 +187,7 @@ def _organize_gene_counts_files(data_dir: Path) -> list[_StudyMetrics]: _log_and_raise_error( ( f"Unequal number of gene count directories and strandedness directories. " - f"Found {len(gene_counts_directories)} gene count directories and {len(strandedness_directories)} strandedness directories." # noqa: E501 + f"Found {len(gene_counts_directories)} gene count directories and {len(strandedness_directories)} strandedness directories." f"\nGene count directory: {gene_count_dir}\nStrandedness directory: {strand_dir}" ), error=ValueError, @@ -210,11 +241,7 @@ async def _process_first_multirun_sample(strand_file: Path, all_counts_files: li run_counts = star_information.count_matrix[["ensembl_gene_id", strand_information]] run_counts.columns = pd.Index(["ensembl_gene_id", "counts"]) - sample_count = ( - run_counts - if sample_count.empty - else sample_count.merge(run_counts, on=["ensembl_gene_id", "counts"], how="outer") - ) + sample_count = run_counts if sample_count.empty else sample_count.merge(run_counts, on=["ensembl_gene_id", "counts"], how="outer") # Set na values to 0 sample_count = sample_count.fillna(value="0") @@ -336,182 +363,253 @@ async def _create_config_df( # noqa: C901 The configuration file created is based on the gene counts matrix. If using zFPKM normalization technique, mean fragment lengths will be fetched """ - gene_counts_dir = como_context_dir / gene_count_dirname - layout_dir = como_context_dir / layout_dirname - strandedness_dir = como_context_dir / strandedness_dirname - fragment_sizes_dir = como_context_dir / fragment_sizes_dirname - prep_method_dir = como_context_dir / prep_method_dirname - - gene_counts_files = list(gene_counts_dir.rglob("*.tab")) - sample_names: list[str] = [] - fragment_lengths: list[int | float] = [] - layouts: list[str] = [] - strands: list[str] = [] - groups: list[str] = [] - preparation_method: list[str] = [] - - if len(gene_counts_files) == 0: + label_regex: Final = re.compile(r"(?PS\d{1,3})(?PR\d{1,3})(?:(?Pr\d{1,3}))?") + gene_counts: list[Path] = list((como_context_dir / gene_count_dirname).rglob("*.tab")) + if not gene_counts: _log_and_raise_error( - f"No gene count files found in '{gene_counts_dir}'.", error=FileNotFoundError, level=LogLevel.ERROR + f"No gene count files found in '{gene_count_dirname}'", + error=FileNotFoundError, + level=LogLevel.ERROR, ) - for gene_count_filename in sorted(gene_counts_files): - # Match S___R___r___ - # \d{1,3} matches 1-3 digits - # (?:r\d{1,3})? optionally matches a "r" followed by three digits - label = re.findall(r"S\d{1,3}R\d{1,3}(?:r\d{1,3})?", gene_count_filename.as_posix())[0] - if not label: + auxillary_directories = { + "layout": como_context_dir / layout_dirname, + "strand": como_context_dir / strandedness_dirname, + "fragment": como_context_dir / fragment_sizes_dirname, + "prep": como_context_dir / prep_method_dirname, + } + aux_lookup: dict[str, dict[str, Path]] = {kind: {} for kind in auxillary_directories} + for kind, root in auxillary_directories.items(): + kind: str + root: Path + for p in root.rglob("*"): + if p.is_file(): + m = label_regex.search(p.stem) + if m: + aux_lookup[kind][m.group(0)] = p + + rows: list[SampleConfiguration] = [] + for gene_count_path in sorted(gene_counts): + m = label_regex.search(gene_count_path.as_posix()) + if not m: _log_and_raise_error( - ( - f"\n\nFilename of '{gene_count_filename}' is not valid. " - f"Should be 'contextName_SXRYrZ.tab', " - f"where X is the study/batch number, Y is the replicate number, " - f"and Z is the run number." - "\n\nIf not a multi-run sample, exclude 'rZ' from the filename." - ), + f"Filename '{gene_count_path.name}' does not match contextName_SXRYrZ.tab pattern", error=ValueError, level=LogLevel.ERROR, ) - - study_number = re.findall(r"S\d{1,3}", label)[0] - rep_number = re.findall(r"R\d{1,3}", label)[0] - run_number = re.findall(r"r\d{1,3}", label) - - multi_flag = 0 - if len(run_number) > 0: - if run_number[0] != "r1": - continue - label_glob = f"{study_number}{rep_number}r*" # S__R__r* - runs = [run for run in gene_counts_files if re.search(label_glob, run.as_posix())] - multi_flag = 1 - frag_files = [] - - for run in runs: - run_number = re.findall(r"R\d{1,3}", run.as_posix())[0] - replicate = re.findall(r"r\d{1,3}", run.as_posix())[0] - frag_filename = "".join([context_name, "_", study_number, run_number, replicate, "_fragment_size.txt"]) - frag_files.append(como_context_dir / fragment_sizes_dirname / study_number / frag_filename) - - layout_files: list[Path] = list(layout_dir.rglob(f"{context_name}_{label}_layout.txt")) - strand_files: list[Path] = list(strandedness_dir.rglob(f"{context_name}_{label}_strandedness.txt")) - frag_files: list[Path] = list(fragment_sizes_dir.rglob(f"{context_name}_{label}_fragment_size.txt")) - prep_files: list[Path] = list(prep_method_dir.rglob(f"{context_name}_{label}_prep_method.txt")) - - layout = "UNKNOWN" - if len(layout_files) == 0: - logger.warning( - f"No layout file found for {label}, writing as 'UNKNOWN', " - f"this should be defined if you are using zFPKM or downstream 'rnaseq_gen.py' will not run" - ) - elif len(layout_files) == 1: - with layout_files[0].open("r") as file: - layout = file.read().strip() - elif len(layout_files) > 1: - _log_and_raise_error( - ( - f"Multiple matching layout files for {label}, " - f"make sure there is only one copy for each replicate in COMO_input" - ), - error=ValueError, - level=LogLevel.ERROR, - ) - - strand = "UNKNOWN" - if len(strand_files) == 0: - logger.warning( - f"No strandedness file found for {label}, writing as 'UNKNOWN'. " - f"This will not interfere with the analysis since you have already set rnaseq_preprocess.py to " - f"infer the strandedness when writing the counts matrix" - ) - elif len(strand_files) == 1: - with strand_files[0].open("r") as file: - strand = file.read().strip() - elif len(strand_files) > 1: - _log_and_raise_error( - ( - f"Multiple matching strandedness files for {label}, " - f"make sure there is only one copy for each replicate in COMO_input" - ), - error=ValueError, - level=LogLevel.ERROR, - ) - - prep = "total" - if len(prep_files) == 0: - logger.warning(f"No prep file found for {label}, assuming 'total', as in 'Total RNA' library preparation") - elif len(prep_files) == 1: - with prep_files[0].open("r") as file: - prep = file.read().strip().lower() - if prep not in ["total", "mrna"]: - _log_and_raise_error( - f"Prep method must be either 'total' or 'mrna' for {label}", - error=ValueError, - level=LogLevel.ERROR, - ) - elif len(prep_files) > 1: + label = m.group(0) + study_number = m["study"] + rep_number = m["rep"] + sample_id = f"{context_name}_{study_number}{rep_number}" + + layout_path = _require_one([aux_lookup["layout"].get(label)], "layout", label) + strand_path = _require_one([aux_lookup["strand"].get(label)], "strand", label) + prep_path = _require_one([aux_lookup["prep"].get(label)], "preparation", label) + + layout, strand, prep = await asyncio.gather( + *[ + _read_text(layout_path, default="UNKNOWN"), + _read_text(strand_path, default="UNKNOWN"), + _read_text(prep_path, default="total", lower=True), + ], + ) + if prep not in {"total", "mrna"}: _log_and_raise_error( - ( - f"Multiple matching prep files for {label}, " - f"make sure there is only one copy for each replicate in COMO_input" - ), + f"Prep method must be 'total' or 'mrna' (got '{prep}') for {label}", error=ValueError, level=LogLevel.ERROR, ) - mean_fragment_size = 100 - if len(frag_files) == 0 and prep != RNAType.TRNA.value: - logger.warning( - f"No fragment file found for {label}, using '100'. " - "You should define this if you are going to use downstream zFPKM normalization" - ) - elif len(frag_files) == 1: - if layout == "single-end": - mean_fragment_size = 0 - else: - if not multi_flag: - frag_df = pd.read_table(frag_files[0], low_memory=False) - frag_df["meanxcount"] = frag_df["frag_mean"] * frag_df["frag_count"] - mean_fragment_size = sum(frag_df["meanxcount"] / sum(frag_df["frag_count"])) - - else: - mean_fragment_sizes = np.array([]) - library_sizes = np.array([]) - for ff in frag_files: - frag_df = pd.read_table(ff, low_memory=False, sep="\t", on_bad_lines="skip") - frag_df["meanxcount"] = frag_df["frag_mean"] * frag_df["frag_count"] - mean_fragment_size = sum(frag_df["meanxcount"] / sum(frag_df["frag_count"])) - mean_fragment_sizes = np.append(mean_fragment_sizes, mean_fragment_size) - library_sizes = np.append(library_sizes, sum(frag_df["frag_count"])) - - mean_fragment_size = sum(mean_fragment_sizes * library_sizes) / sum(library_sizes) - elif len(frag_files) > 1: - _log_and_raise_error( - ( - f"Multiple matching fragment files for {label}, " - f"make sure there is only one copy for each replicate in COMO_input" - ), - error=ValueError, - level=LogLevel.ERROR, + fragment_label = f"{context_name}_{label}_fragment_size.txt" + frag_paths = [p for p in aux_lookup["fragment"].values() if p.name == fragment_label] + if not frag_paths and prep != RNAType.TRNA.value: + logger.warning(f"No fragment file for '{label}'; defaulting to 100 bp (needed for zFPKM).") + mean_frag = 100.0 + elif len(frag_paths) == 1 and layout == "single-end": + mean_frag = 0.0 + else: # 1-N files, paired end + dfs: list[pd.DataFrame] = await asyncio.gather(*[_read_file(f, sep="\t", on_bad_lines="skip") for f in frag_paths]) + for df in dfs: + df["meanxcount"] = df["frag_mean"] * df["frag_count"] + counts = np.array([df["frag_count"].sum() for df in dfs]) + means = np.array([(df["meanxcount"] / df["frag_count"].sum()).sum() for df in dfs]) + mean_frag = float(np.average(means, weights=counts)) + rows.append( + SampleConfiguration( + sample_name=sample_id, + fragment_length=mean_frag, + layout=layout, + strand=strand, + study=study_number, + library_prep=prep, ) + ) - sample_names.append(f"{context_name}_{study_number}{rep_number}") - fragment_lengths.append(mean_fragment_size) - layouts.append(layout) - strands.append(strand) - groups.append(study_number) - preparation_method.append(prep) - - out_df = pd.DataFrame( - { - "sample_name": sample_names, - "fragment_length": fragment_lengths, - "layout": layouts, - "strand": strands, - "study": groups, - "library_prep": preparation_method, - } - ).sort_values("sample_name") - return out_df + df = pd.DataFrame.from_records([asdict(r) for r in rows]).sort_values("sample_name", ignore_index=True) + return df + + # 6-3-25: Intentionally left commented-out code to test its replacement + # gene_counts_dir = como_context_dir / gene_count_dirname + # layout_dir = como_context_dir / layout_dirname + # strandedness_dir = como_context_dir / strandedness_dirname + # fragment_sizes_dir = como_context_dir / fragment_sizes_dirname + # prep_method_dir = como_context_dir / prep_method_dirname + # + # gene_counts_files = list(gene_counts_dir.rglob("*.tab")) + # sample_names: list[str] = [] + # fragment_lengths: list[int | float] = [] + # layouts: list[str] = [] + # strands: list[str] = [] + # groups: list[str] = [] + # preparation_method: list[str] = [] + # + # if len(gene_counts_files) == 0: + # _log_and_raise_error(f"No gene count files found in '{gene_counts_dir}'.", error=FileNotFoundError, level=LogLevel.ERROR) + # + # for gene_count_filename in sorted(gene_counts_files): + # # Match S___R___r___ + # # \d{1,3} matches 1-3 digits + # # (?:r\d{1,3})? optionally matches a "r" followed by three digits + # label = re.findall(r"S\d{1,3}R\d{1,3}(?:r\d{1,3})?", gene_count_filename.as_posix())[0] + # if not label: + # _log_and_raise_error( + # ( + # f"\n\nFilename of '{gene_count_filename}' is not valid. " + # f"Should be 'contextName_SXRYrZ.tab', " + # f"where X is the study/batch number, Y is the replicate number, " + # f"and Z is the run number." + # "\n\nIf not a multi-run sample, exclude 'rZ' from the filename." + # ), + # error=ValueError, + # level=LogLevel.ERROR, + # ) + # + # study_number = re.findall(r"S\d{1,3}", label)[0] + # rep_number = re.findall(r"R\d{1,3}", label)[0] + # run_number = re.findall(r"r\d{1,3}", label) + # + # multi_flag = 0 + # if len(run_number) > 0: + # if run_number[0] != "r1": + # continue + # label_glob = f"{study_number}{rep_number}r*" # S__R__r* + # runs = [run for run in gene_counts_files if re.search(label_glob, run.as_posix())] + # multi_flag = 1 + # frag_files = [] + # + # for run in runs: + # run_number = re.findall(r"R\d{1,3}", run.as_posix())[0] + # replicate = re.findall(r"r\d{1,3}", run.as_posix())[0] + # frag_filename = "".join([context_name, "_", study_number, run_number, replicate, "_fragment_size.txt"]) + # frag_files.append(como_context_dir / fragment_sizes_dirname / study_number / frag_filename) + # + # layout_files: list[Path] = list(layout_dir.rglob(f"{context_name}_{label}_layout.txt")) + # strand_files: list[Path] = list(strandedness_dir.rglob(f"{context_name}_{label}_strandedness.txt")) + # frag_files: list[Path] = list(fragment_sizes_dir.rglob(f"{context_name}_{label}_fragment_size.txt")) + # prep_files: list[Path] = list(prep_method_dir.rglob(f"{context_name}_{label}_prep_method.txt")) + # + # layout = "UNKNOWN" + # if len(layout_files) == 0: + # logger.warning( + # f"No layout file found for {label}, writing as 'UNKNOWN', " + # f"this should be defined if you are using zFPKM or downstream 'rnaseq_gen.py' will not run" + # ) + # elif len(layout_files) == 1: + # with layout_files[0].open("r") as file: + # layout = file.read().strip() + # elif len(layout_files) > 1: + # _log_and_raise_error( + # f"Multiple matching layout files for {label}, make sure there is only one copy for each replicate in COMO_input", + # error=ValueError, + # level=LogLevel.ERROR, + # ) + # + # strand = "UNKNOWN" + # if len(strand_files) == 0: + # logger.warning( + # f"No strandedness file found for {label}, writing as 'UNKNOWN'. " + # f"This will not interfere with the analysis since you have already set rnaseq_preprocess.py to " + # f"infer the strandedness when writing the counts matrix" + # ) + # elif len(strand_files) == 1: + # with strand_files[0].open("r") as file: + # strand = file.read().strip() + # elif len(strand_files) > 1: + # _log_and_raise_error( + # f"Multiple matching strandedness files for {label}, make sure there is only one copy for each replicate in COMO_input", + # error=ValueError, + # level=LogLevel.ERROR, + # ) + # + # prep = "total" + # if len(prep_files) == 0: + # logger.warning(f"No prep file found for {label}, assuming 'total', as in 'Total RNA' library preparation") + # elif len(prep_files) == 1: + # with prep_files[0].open("r") as file: + # prep = file.read().strip().lower() + # if prep not in ["total", "mrna"]: + # _log_and_raise_error( + # f"Prep method must be either 'total' or 'mrna' for {label}", + # error=ValueError, + # level=LogLevel.ERROR, + # ) + # elif len(prep_files) > 1: + # _log_and_raise_error( + # f"Multiple matching prep files for {label}, make sure there is only one copy for each replicate in COMO_input", + # error=ValueError, + # level=LogLevel.ERROR, + # ) + # + # mean_fragment_size = 100 + # if len(frag_files) == 0 and prep != RNAType.TRNA.value: + # logger.warning( + # f"No fragment file found for {label}, using '100'. You should define this if you are going to use downstream zFPKM normalization" + # ) + # elif len(frag_files) == 1: + # if layout == "single-end": + # mean_fragment_size = 0 + # else: + # if not multi_flag: + # frag_df = pd.read_table(frag_files[0], low_memory=False) + # frag_df["meanxcount"] = frag_df["frag_mean"] * frag_df["frag_count"] + # mean_fragment_size = sum(frag_df["meanxcount"] / sum(frag_df["frag_count"])) + # + # else: + # mean_fragment_sizes = np.array([]) + # library_sizes = np.array([]) + # for ff in frag_files: + # frag_df = pd.read_table(ff, low_memory=False, sep="\t", on_bad_lines="skip") + # frag_df["meanxcount"] = frag_df["frag_mean"] * frag_df["frag_count"] + # mean_fragment_size = sum(frag_df["meanxcount"] / sum(frag_df["frag_count"])) + # mean_fragment_sizes = np.append(mean_fragment_sizes, mean_fragment_size) + # library_sizes = np.append(library_sizes, sum(frag_df["frag_count"])) + # + # mean_fragment_size = sum(mean_fragment_sizes * library_sizes) / sum(library_sizes) + # elif len(frag_files) > 1: + # _log_and_raise_error( + # f"Multiple matching fragment files for {label}, make sure there is only one copy for each replicate in COMO_input", + # error=ValueError, + # level=LogLevel.ERROR, + # ) + # + # sample_names.append(f"{context_name}_{study_number}{rep_number}") + # fragment_lengths.append(mean_fragment_size) + # layouts.append(layout) + # strands.append(strand) + # groups.append(study_number) + # preparation_method.append(prep) + # + # out_df = pd.DataFrame( + # { + # "sample_name": sample_names, + # "fragment_length": fragment_lengths, + # "layout": layouts, + # "strand": strands, + # "study": groups, + # "library_prep": preparation_method, + # } + # ).sort_values("sample_name") + # return out_df async def _create_gene_info_file( @@ -584,7 +682,7 @@ async def read_counts(file: Path) -> list[str]: logger.success(f"Gene Info file written at '{output_filepath}'") -async def _create_matrix_file( +async def _process_como_input( context_name: str, output_config_filepath: Path, como_context_dir: PATH_TYPE, @@ -626,7 +724,7 @@ async def _process( for rna, output_config_filepath, output_matrix_filepath in rna_types: tasks.append( asyncio.create_task( - _create_matrix_file( + _process_como_input( context_name=context_name, output_config_filepath=output_config_filepath, como_context_dir=como_context_dir, @@ -639,12 +737,15 @@ async def _process( await asyncio.gather(*tasks) # create the gene info filepath based on provided data + + input_files = [] + if input_matrix_filepath: + input_files.extend(input_matrix_filepath) + output_trna_matrix_filepath and input_files.append(output_trna_matrix_filepath) + output_mrna_matrix_filepath and input_files.append(output_mrna_matrix_filepath) + await _create_gene_info_file( - counts_matrix_filepaths=[ - f - for f in [*input_matrix_filepath, output_trna_matrix_filepath, output_mrna_matrix_filepath] - if f is not None - ], + counts_matrix_filepaths=input_files, output_filepath=output_gene_info_filepath, taxon=taxon, cache=cache, @@ -662,7 +763,7 @@ async def rnaseq_preprocess( output_trna_count_matrix_filepath: Path | None = None, output_mrna_count_matrix_filepath: Path | None = None, cache: bool = True, - log_level: LogLevel = LogLevel.INFO, + log_level: LogLevel | str = LogLevel.INFO, log_location: str | TextIOWrapper = sys.stderr, ) -> None: """Preprocesses RNA-seq data for downstream analysis. @@ -691,22 +792,10 @@ async def rnaseq_preprocess( if como_context_dir: como_context_dir = como_context_dir.resolve() input_matrix_filepath = [i.resolve() for i in _listify(input_matrix_filepath)] if input_matrix_filepath else None - output_trna_metadata_filepath = ( - output_trna_metadata_filepath.resolve() if output_trna_metadata_filepath else output_trna_metadata_filepath - ) - output_mrna_metadata_filepath = ( - output_mrna_metadata_filepath.resolve() if output_mrna_metadata_filepath else output_mrna_metadata_filepath - ) - output_trna_count_matrix_filepath = ( - output_trna_count_matrix_filepath.resolve() - if output_trna_count_matrix_filepath - else output_trna_count_matrix_filepath - ) - output_mrna_count_matrix_filepath = ( - output_mrna_count_matrix_filepath.resolve() - if output_mrna_count_matrix_filepath - else output_mrna_count_matrix_filepath - ) + output_trna_metadata_filepath = output_trna_metadata_filepath.resolve() if output_trna_metadata_filepath else None + output_mrna_metadata_filepath = output_mrna_metadata_filepath.resolve() if output_mrna_metadata_filepath else None + output_trna_count_matrix_filepath = output_trna_count_matrix_filepath.resolve() if output_trna_count_matrix_filepath else None + output_mrna_count_matrix_filepath = output_mrna_count_matrix_filepath.resolve() if output_mrna_count_matrix_filepath else None await _process( context_name=context_name, From 8c71b577de32c559d72e139d4aa9185d56162836 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 3 Jun 2025 16:20:34 -0500 Subject: [PATCH 203/265] refactor: add logging Signed-off-by: Josh Loecker --- main/como/rnaseq_preprocess.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index e4c7c416..aa4aaf32 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -643,10 +643,7 @@ async def read_counts(file: Path) -> list[str]: # Remove NA values from entrez_gene_id dataframe column return conversion["entrez_gene_id"].dropna().tolist() - logger.info( - "Fetching gene info - " - "this can take up to 5 minutes depending on the number of genes and your internet connection" - ) + logger.info("Fetching gene info - this can take up to 5 minutes depending on the number of genes and your internet connection") genes = set(chain.from_iterable(await asyncio.gather(*[read_counts(f) for f in counts_matrix_filepaths]))) gene_data = await MyGene(cache=cache).query(items=list(genes), taxon=taxon, scopes="entrezgene") gene_info: pd.DataFrame = pd.DataFrame( From b632a7257a57025108528142131bedc3ad1584df Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 3 Jun 2025 16:22:17 -0500 Subject: [PATCH 204/265] refactor: added slots to dataclass for reduced memory usage; ruff formatting Signed-off-by: Josh Loecker --- main/como/rnaseq_gen.py | 80 ++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 46 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 13181f30..e7f109e7 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -45,7 +45,7 @@ class LayoutMethod(Enum): single_end = "single-end" -@dataclass +@dataclass(slots=True) class _StudyMetrics: study: str num_samples: int @@ -118,7 +118,7 @@ def k_over_a(k: int, a: float) -> Callable[[npt.NDArray], bool]: :param k: The minimum number of times the sum of elements must be greater than or equal to A. :param a: The value to compare the sum of elements to. :return: A function that accepts a NumPy array to perform the actual filtering - """ # noqa: E501 + """ def filter_func(row: npt.NDArray) -> bool: return np.sum(row >= a) >= k @@ -142,11 +142,7 @@ def genefilter(data: pd.DataFrame | npt.NDArray, filter_func: Callable[[npt.NDAr level=LogLevel.CRITICAL, ) - return ( - data.apply(filter_func, axis=1).values - if isinstance(data, pd.DataFrame) - else np.apply_along_axis(filter_func, axis=1, arr=data) - ) + return data.apply(filter_func, axis=1).values if isinstance(data, pd.DataFrame) else np.apply_along_axis(filter_func, axis=1, arr=data) async def _build_matrix_results( @@ -233,7 +229,7 @@ def calculate_tpm(metrics: NamedMetrics) -> NamedMetrics: def _calculate_fpkm(metrics: NamedMetrics, scale: int = 1e6) -> NamedMetrics: - """Calculate the Fragments Per Kilobase of transcript per Million mapped reads (FPKM) for each sample in the metrics dictionary.""" # noqa: E501 + """Calculate the Fragments Per Kilobase of transcript per Million mapped reads (FPKM) for each sample in the metrics dictionary.""" for study in metrics: matrix_values = [] for sample in range(metrics[study].num_samples): @@ -277,7 +273,6 @@ def _calculate_fpkm(metrics: NamedMetrics, scale: int = 1e6) -> NamedMetrics: return metrics -# def _zfpkm_calculation(row: pd.Series, kernel: KernelDensity, peak_parameters: tuple[float, float]) -> _ZFPKMResult: def _zfpkm_calculation( column: pd.Series, peak_parameters: PeakIdentificationParameters, @@ -356,10 +351,7 @@ def zfpkm_transform( ) -> tuple[dict[str, _ZFPKMResult], DataFrame]: """Perform zFPKM calculation/transformation.""" if update_every_percent > 1: - logger.warning( - f"update_every_percent should be a decimal value between 0 and 1; got: {update_every_percent} - " - f"will convert to percentage" - ) + logger.warning(f"update_every_percent should be a decimal value between 0 and 1; got: {update_every_percent} - will convert to percentage") update_every_percent /= 100 total_samples = _num_columns(fpkm_df) @@ -367,16 +359,13 @@ def zfpkm_transform( # Get at least 1 core and at most cpu_count() - 2 cores = max(min(multiprocessing.cpu_count() - 2, total_samples), 1) - logger.debug( - f"zFPKM transforming {len(fpkm_df.columns)} sample(s) " - f"containing {len(fpkm_df):,} genes(s) using {cores} core(s)" - ) + logger.debug(f"zFPKM transforming {len(fpkm_df.columns)} sample(s) containing {len(fpkm_df):,} genes(s) using {cores} core(s)") logger.debug(f"Will update every {update_per_step:,} steps (~{update_every_percent:.1%} of {total_samples:,})") chunk_time = time.time() start_time = time.time() log_padding = len(str(f"{total_samples:,}")) - zfpkm_series: list[pd.Series | None] = [None] * total_samples + zfpkm_series: list[pd.Series] = [] results: dict[str, _ZFPKMResult] = {} with ProcessPoolExecutor(max_workers=cores) as pool: @@ -393,7 +382,7 @@ def zfpkm_transform( result = future.result() key = str(result.zfpkm.name) results[key] = result - zfpkm_series[i] = result.zfpkm + zfpkm_series.append(result.zfpkm) if i != 0 and ((i + 1) % update_per_step == 0 or (i + 1) == total_samples): current_time = time.time() @@ -522,11 +511,7 @@ def cpm_filter( top_samples = round(n_top * len(counts.columns)) # noqa: F841 test_bools = pd.DataFrame({"entrez_gene_ids": entrez_ids}) for i in range(len(counts_per_million.columns)): - cutoff = ( - 10e6 / (np.median(np.sum(counts[:, i]))) - if cut_off == "default" - else (1e6 * cut_off) / np.median(np.sum(counts[:, i])) - ) + cutoff = 10e6 / (np.median(np.sum(counts[:, i]))) if cut_off == "default" else (1e6 * cut_off) / np.median(np.sum(counts[:, i])) test_bools = test_bools.merge(counts_per_million[counts_per_million.iloc[:, i] > cutoff]) return metrics @@ -595,28 +580,28 @@ def zfpkm_filter( cut_off = filtering_options.cut_off metrics = _calculate_fpkm(metrics) if calculate_fpkm else metrics - metric: _StudyMetrics for metric in metrics.values(): + metric: _StudyMetrics # if fpkm was not calculated, the normalization matrix will be empty; collect the count matrix instead matrix = metric.count_matrix if metric.normalization_matrix.empty else metric.normalization_matrix matrix = matrix[matrix.sum(axis=1) > 0] # remove rows (genes) that have no counts across all samples - minimums = matrix == 0 results, zfpkm_df = zfpkm_transform(matrix, peak_parameters=peak_parameters, bandwidth=bandwidth) - zfpkm_df[minimums] = -4 + zfpkm_df[(matrix == 0) | (zfpkm_df.isna())] = -4 if len(results) > 10 and not force_zfpkm_plot: logger.warning( "Not plotting zFPKM results because more than 10 plots would be created. " "If you would like to plot them anyway, set 'force_zfpkm_plot' to True" ) + elif output_png_filepath is None: + logger.critical("Output zFPKM PNG filepath is None, set a path to plot zFPKM graphs") else: - if output_png_filepath is None: - logger.critical("Output zFPKM PNG filepath is None, set a path to plot zFPKM graphs") - else: - output_png_filepath.parent.mkdir(parents=True, exist_ok=True) - output_png_filepath.unlink(missing_ok=True) - zfpkm_plot(results, output_png_filepath=output_png_filepath) + output_png_filepath.parent.mkdir(parents=True, exist_ok=True) + output_png_filepath.unlink(missing_ok=True) + zfpkm_plot(results, output_png_filepath=output_png_filepath) + + metric.z_score_matrix = zfpkm_df # determine which genes are expressed min_samples = round(min_sample_expression * len(zfpkm_df.columns)) @@ -759,16 +744,25 @@ async def _process( ) ) + merged_zscore_df = ( + metric.z_score_matrix + if merged_zscore_df.empty + else merged_zscore_df.merge( + metric.z_score_matrix, + how="outer", + left_index=True, + right_index=True, + ) + ) + merged_zscore_df[merged_zscore_df.isna()] = -4 + # If any of the normalization metrics are not empty, write the normalized metrics to disk if not all(metric.normalization_matrix.empty for metric in metrics.values()): - merged_zscore_df.index = pd.Series(entrez_gene_ids, name="entrez_gene_id") - merged_zscore_df.dropna(inplace=True) merged_zscore_df.to_csv(output_zscore_normalization_filepath, index=True) logger.success(f"Wrote z-score normalization matrix to {output_zscore_normalization_filepath}") else: logger.warning( - "Not writing z-score normalization matrix because no normalization matrices exist. " - "This is expected if you are using UMI filtering." + "Not writing z-score normalization matrix because no normalization matrices exist. This is expected if you are using UMI filtering." ) expression_frequency = pd.Series(expressed_genes).value_counts() @@ -791,14 +785,11 @@ async def _process( boolean_matrix.loc[gene, "high"] = 1 expressed_count = len(boolean_matrix[boolean_matrix["expressed"] == 1]) - high_confidence_count = len(boolean_matrix[boolean_matrix["high"] == 1]) - expressed_count + high_confidence_count = len(boolean_matrix[boolean_matrix["high"] == 1]) boolean_matrix.dropna(subset="entrez_gene_id", inplace=True) boolean_matrix.to_csv(output_boolean_activity_filepath, index=False) - logger.info( - f"{context_name} - Found {expressed_count} expressed genes, " - f"{high_confidence_count} of which are confidently expressed" - ) + logger.info(f"{context_name} - Found {expressed_count} expressed genes, {high_confidence_count} of which are confidently expressed") logger.success(f"Wrote boolean matrix to {output_boolean_activity_filepath}") @@ -909,10 +900,7 @@ async def rnaseq_gen( # noqa: C901 elif isinstance(input_metadata_filepath_or_df, Path): if input_metadata_filepath_or_df.suffix not in {".xlsx", ".xls"}: _log_and_raise_error( - ( - f"Expected an excel file with extension of '.xlsx' or '.xls', " - f"got '{input_metadata_filepath_or_df.suffix}'." - ), + f"Expected an excel file with extension of '.xlsx' or '.xls', got '{input_metadata_filepath_or_df.suffix}'.", error=ValueError, level=LogLevel.ERROR, ) From f651a85b8812e29ba5fd5618dbfa691fde885f49 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 3 Jun 2025 16:22:53 -0500 Subject: [PATCH 205/265] refactor: better managing/converting of ensembl and entrez gene IDs Signed-off-by: Josh Loecker --- main/como/rnaseq_gen.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index e7f109e7..97b64958 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -164,7 +164,22 @@ async def _build_matrix_results( conversion["ensembl_gene_id"] = conversion["ensembl_gene_id"].str.split(",") conversion = conversion.explode("ensembl_gene_id") conversion.reset_index(inplace=True, drop=True) - matrix = matrix.merge(conversion, on=["ensembl_gene_id", "entrez_gene_id", "gene_symbol"], how="left") + + merge_on = [] + if "ensembl_gene_id" in matrix.columns and "ensembl_gene_id" in conversion.columns: + merge_on.append("ensembl_gene_id") + if "entrez_gene_id" in matrix.columns and "entrez_gene_id" in conversion.columns: + merge_on.append("entrez_gene_id") + if "gene_symbol" in matrix.columns and "gene_symbol" in conversion.columns: + merge_on.append("gene_symbol") + + if not merge_on: + _log_and_raise_error( + "No columns to merge on. Tested 'ensembl_gene_id', 'entrez_gene_id', and 'gene_symbol'. Please check your input files.", + error=ValueError, + level=LogLevel.ERROR, + ) + matrix = matrix.merge(conversion, on=merge_on, how="left") # Only include Entrez and Ensembl Gene IDs that are present in `gene_info` matrix["entrez_gene_id"] = matrix["entrez_gene_id"].str.split("//") @@ -734,15 +749,6 @@ async def _process( for metric in metrics.values(): expressed_genes.extend(metric.entrez_gene_ids) top_genes.extend(metric.high_confidence_entrez_gene_ids) - if not metric.normalization_matrix.empty: - merged_zscore_df = ( - metric.z_score_matrix - if merged_zscore_df.empty - else pd.concat( - [merged_zscore_df, metric.z_score_matrix], - axis=1, - ) - ) merged_zscore_df = ( metric.z_score_matrix From 5a30cede35b0270755c7c18f1db2a5ace44361c4 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 3 Jun 2025 16:23:19 -0500 Subject: [PATCH 206/265] refactor: more efficient tpm calculation Signed-off-by: Josh Loecker --- main/como/rnaseq_gen.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 97b64958..f4372c9b 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -229,15 +229,12 @@ def calculate_tpm(metrics: NamedMetrics) -> NamedMetrics: for sample in metrics: count_matrix = metrics[sample].count_matrix - gene_sizes = metrics[sample].gene_sizes - - tpm_matrix = pd.DataFrame(data=None, index=count_matrix.index, columns=count_matrix.columns) - for i in range(len(count_matrix.columns)): - values: pd.Series = count_matrix.iloc[:, i] + 1 # Add 1 to prevent division by 0 - rate = np.log(values.tolist()) - np.log(gene_sizes) - denominator = np.log(np.sum(np.exp(rate))) - tpm_value = np.exp(rate - denominator + np.log(1e6)) - tpm_matrix.iloc[:, i] = tpm_value + gene_sizes = pd.Series(metrics[sample].gene_sizes, index=count_matrix.index) + adjusted_counts = count_matrix.add(1e-6) + + tpm_matrix = adjusted_counts.divide(gene_sizes, axis=0) # (count + 1) / gene_length + tpm_matrix = tpm_matrix.div(tpm_matrix.sum(axis=0), axis=1) # normalize by total + tpm_matrix = tpm_matrix.mul(1e6) # scale to per-million metrics[sample].normalization_matrix = tpm_matrix return metrics From 645eeef3360bec63a3869c953abc3051cf497ed7 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 3 Jun 2025 16:23:57 -0500 Subject: [PATCH 207/265] refactor: use pandas dataframes instead of numpy arrays for developer ease-of-use Signed-off-by: Josh Loecker --- main/como/rnaseq_gen.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index f4372c9b..57424d3a 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -246,7 +246,7 @@ def _calculate_fpkm(metrics: NamedMetrics, scale: int = 1e6) -> NamedMetrics: matrix_values = [] for sample in range(metrics[study].num_samples): layout = metrics[study].layout[sample] - count_matrix: npt.NDArray = metrics[study].count_matrix.iloc[:, sample].values.astype(np.float32) + count_matrix: pd.DataFrame = metrics[study].count_matrix.iloc[:, sample].values.astype(np.float32) gene_lengths = ( metrics[study].fragment_lengths[sample].astype(np.float32) if layout == LayoutMethod.paired_end @@ -257,12 +257,15 @@ def _calculate_fpkm(metrics: NamedMetrics, scale: int = 1e6) -> NamedMetrics: match layout: case LayoutMethod.paired_end: # FPKM total_fragments = count_matrix.sum(axis=0) - counts_per_million = total_fragments / scale - fragments_per_kilobase = count_matrix / gene_lengths_kb[:, np.newaxis] - fragments_per_kilobase_million = fragments_per_kilobase / counts_per_million + if total_fragments == 0: + fragments_per_kilobase_million = np.nan + else: + counts_per_million = total_fragments / scale + fragments_per_kilobase = count_matrix / gene_lengths_kb + fragments_per_kilobase_million = fragments_per_kilobase / counts_per_million matrix_values.append(fragments_per_kilobase_million) case LayoutMethod.single_end: # RPKM - reads_per_kilobase = count_matrix / gene_lengths_kb[: np.newaxis] + reads_per_kilobase = count_matrix / gene_lengths_kb total_reads = count_matrix.sum(axis=0) counts_per_million = total_reads / scale reads_per_kilobase_million = reads_per_kilobase / counts_per_million @@ -277,7 +280,11 @@ def _calculate_fpkm(metrics: NamedMetrics, scale: int = 1e6) -> NamedMetrics: level=LogLevel.ERROR, ) - fpkm_matrix = pd.DataFrame(matrix_values).T # Transpose is needed because values were appended as rows + # Transpose is needed because values were appended as rows + fpkm_matrix = pd.DataFrame(matrix_values).T + fpkm_matrix.index = metrics[study].count_matrix.index + fpkm_matrix.columns = metrics[study].sample_names + fpkm_matrix = fpkm_matrix[~pd.isna(fpkm_matrix)] metrics[study].normalization_matrix = fpkm_matrix metrics[study].normalization_matrix.columns = metrics[study].count_matrix.columns From 146a8069039a22454ff4185f75f9d5960cfb3312 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 3 Jun 2025 16:24:17 -0500 Subject: [PATCH 208/265] refactor: fix plot generation Signed-off-by: Josh Loecker --- main/como/rnaseq_gen.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 57424d3a..a3c798c3 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -453,11 +453,11 @@ def zfpkm_plot(results, *, output_png_filepath: Path, plot_xfloor: int = -4): mega_df.columns = pd.Series(data=["sample_name", "log2fpkm", "fpkm_density", "fitted_density_scaled"]) mega_df = mega_df.melt(id_vars=["log2fpkm", "sample_name"], var_name="source", value_name="density") - fig, axes = plt.subplot(len(results), 1, figsize=(8, 4 * len(results))) + fig, axes = plt.subplots(nrows=len(results), ncols=1, figsize=(8, 4 * len(results))) if len(results) == 1: axes = [axes] - for i, sample_name in enumerate(results, start=1): + for i, sample_name in enumerate(results): sample_data = mega_df[mega_df["sample_name"] == sample_name] axis = axes[i] @@ -472,9 +472,7 @@ def zfpkm_plot(results, *, output_png_filepath: Path, plot_xfloor: int = -4): plt.tight_layout() if output_png_filepath.suffix != ".png": - logger.warning( - f"Output filepath did not end in '.png', setting to '.png' now. Got: '{output_png_filepath.suffix}'" - ) + logger.warning(f"Output filepath did not end in '.png', setting to '.png' now. Got: '{output_png_filepath.suffix}'") output_png_filepath = output_png_filepath.with_suffix(".png") plt.savefig(output_png_filepath) @@ -483,9 +481,7 @@ def calculate_z_score(metrics: NamedMetrics) -> NamedMetrics: """Calculate the z-score for each sample in the metrics dictionary.""" for sample in metrics: log_matrix = np.log(metrics[sample].normalization_matrix) - z_matrix = pd.DataFrame( - data=sklearn.preprocessing.scale(log_matrix, axis=1), columns=metrics[sample].sample_names - ) + z_matrix = pd.DataFrame(data=sklearn.preprocessing.scale(log_matrix, axis=1), columns=metrics[sample].sample_names) metrics[sample].z_score_matrix = z_matrix return metrics From a9d78007bf341c93a5f597a3c5b56ba292041b6d Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 3 Jun 2025 16:24:42 -0500 Subject: [PATCH 209/265] refactor: ruff formatting Signed-off-by: Josh Loecker --- main/como/rnaseq_gen.py | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index a3c798c3..e2e988d4 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -552,12 +552,8 @@ def tpm_quantile_filter(*, metrics: NamedMetrics, filtering_options: _FilteringO top_samples = round(n_top * len(tpm_matrix.columns)) tpm_quantile = tpm_matrix[tpm_matrix > 0] - quantile_cutoff = np.quantile( - a=tpm_quantile.values, q=1 - (cut_off / 100), axis=0 - ) # Compute quantile across columns - boolean_expression = pd.DataFrame( - data=tpm_matrix > quantile_cutoff, index=tpm_matrix.index, columns=tpm_matrix.columns - ).astype(int) + quantile_cutoff = np.quantile(a=tpm_quantile.values, q=1 - (cut_off / 100), axis=0) # Compute quantile across columns + boolean_expression = pd.DataFrame(data=tpm_matrix > quantile_cutoff, index=tpm_matrix.index, columns=tpm_matrix.columns).astype(int) min_func = k_over_a(min_samples, 0.9) top_func = k_over_a(top_samples, 0.9) @@ -648,9 +644,7 @@ def filter_counts( """Filter the count matrix based on the specified technique.""" match technique: case FilteringTechnique.CPM: - return cpm_filter( - context_name=context_name, metrics=metrics, filtering_options=filtering_options, prep=prep - ) + return cpm_filter(context_name=context_name, metrics=metrics, filtering_options=filtering_options, prep=prep) case FilteringTechnique.TPM: return tpm_quantile_filter(metrics=metrics, filtering_options=filtering_options) case FilteringTechnique.ZFPKM: @@ -707,9 +701,7 @@ async def _process( rnaseq_matrix: pd.DataFrame = await _read_file(rnaseq_matrix_filepath) if rnaseq_matrix_filepath.suffix == ".h5ad": - conversion = await gene_symbol_to_ensembl_and_gene_id( - symbols=rnaseq_matrix["gene_symbol"].tolist(), taxon=taxon - ) + conversion = await gene_symbol_to_ensembl_and_gene_id(symbols=rnaseq_matrix["gene_symbol"].tolist(), taxon=taxon) conversion.reset_index(inplace=True) rnaseq_matrix = rnaseq_matrix.merge(conversion, how="left", on="gene_symbol") rnaseq_matrix.replace(to_replace=pd.NA, value="-") @@ -728,6 +720,7 @@ async def _process( metadata_df=metadata_df, taxon=taxon, ) + metrics = read_counts_results.metrics entrez_gene_ids = read_counts_results.entrez_gene_ids @@ -772,9 +765,7 @@ async def _process( ) expression_frequency = pd.Series(expressed_genes).value_counts() - expression_df = pd.DataFrame( - {"entrez_gene_id": expression_frequency.index, "frequency": expression_frequency.values} - ) + expression_df = pd.DataFrame({"entrez_gene_id": expression_frequency.index, "frequency": expression_frequency.values}) expression_df["prop"] = expression_df["frequency"] / len(metrics) expression_df = expression_df[expression_df["prop"] >= filtering_options.batch_ratio] From 992469a673883ce0fed1e3fd54ee3fe4d896197e Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 3 Jun 2025 16:25:25 -0500 Subject: [PATCH 210/265] refactor: ruff formatting Signed-off-by: Josh Loecker --- main/como/combine_distributions.py | 32 ++++++++---------------------- 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index 3571f122..9717eca1 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -43,10 +43,7 @@ async def _combine_z_distribution_for_batch( f"context: '{context_name}'" ) if _num_columns(matrix) < 2: - logger.trace( - f"A single sample exists for batch '{batch.batch_num}'. " - f"Returning as-is because no additional combining can be done" - ) + logger.trace(f"A single sample exists for batch '{batch.batch_num}'. Returning as-is because no additional combining can be done") return matrix values = matrix.iloc[:, 1:].values @@ -147,16 +144,12 @@ def _combine_z_distribution_for_context( return pd.DataFrame({"ensembl_gene_id": [], "combine_z": []}) z_matrices = [ - res.z_score_matrix.set_index("ensembl_gene_id").rename( - columns={col: res.type.value for col in res.z_score_matrix.columns[1:]} - ) + res.z_score_matrix.set_index("ensembl_gene_id").rename(columns={col: res.type.value for col in res.z_score_matrix.columns[1:]}) for res in zscore_results ] z_matrix = pd.concat(z_matrices, axis=1, join="outer").reset_index() if _num_columns(z_matrix) <= 1: - logger.trace( - f"Only 1 source exists for '{context}', returning dataframe as-is becuase no data exists to combine" - ) + logger.trace(f"Only 1 source exists for '{context}', returning dataframe as-is becuase no data exists to combine") z_matrix.columns = ["ensembl_gene_id", "combine_z"] return z_matrix @@ -232,8 +225,7 @@ async def _begin_combining_distributions( matrix=matrix[[GeneIdentifier.ENSEMBL_GENE_ID.value, *batch.sample_names]], source=source, output_combined_matrix_filepath=( - output_filepaths[source.value].parent - / f"{context_name}_{source.value}_batch{batch.batch_num}_combined_z_distribution_.csv" + output_filepaths[source.value].parent / f"{context_name}_{source.value}_batch{batch.batch_num}_combined_z_distribution_.csv" ), output_figure_dirpath=output_figure_dirpath, weighted_z_floor=weighted_z_floor, @@ -245,21 +237,16 @@ async def _begin_combining_distributions( merged_batch_results = pd.DataFrame() for df in batch_results: - merged_batch_results = ( - df if merged_batch_results.empty else merged_batch_results.merge(df, on="ensembl_gene_id", how="outer") - ) + merged_batch_results = df if merged_batch_results.empty else merged_batch_results.merge(df, on="ensembl_gene_id", how="outer") merged_source_results: pd.DataFrame = await _combine_z_distribution_for_source( merged_source_data=merged_batch_results, context_name=context_name, num_replicates=sum(batch.num_samples for batch in batch_names[source.value]), output_combined_matrix_filepath=( - output_filepaths[source.value].parent - / f"{context_name}_{source.value}_combined_zscore_distribution.csv" - ), - output_figure_filepath=( - output_figure_dirpath / f"{context_name}_{source.value}_combined_zscore_distribution.pdf" + output_filepaths[source.value].parent / f"{context_name}_{source.value}_combined_zscore_distribution.csv" ), + output_figure_filepath=(output_figure_dirpath / f"{context_name}_{source.value}_combined_zscore_distribution.pdf"), weighted_z_floor=weighted_z_floor, weighted_z_ceiling=weighted_z_ceiling, ) @@ -271,10 +258,7 @@ async def _begin_combining_distributions( ) ) merged_source_results.to_csv(output_filepaths[source.value]) - logger.success( - f"Wrote z-scores for source '{source.value}' " - f"in context '{context_name}' to '{output_filepaths[source.value]}'" - ) + logger.success(f"Wrote z-scores for source '{source.value}' in context '{context_name}' to '{output_filepaths[source.value]}'") logger.trace(f"Combining z-score distributions for all sources in context '{context_name}'") merged_context_results = _combine_z_distribution_for_context( From 8c00a1fc08b160f8cc43b20987e650b12721dd49 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 3 Jun 2025 16:26:37 -0500 Subject: [PATCH 211/265] refactor: ruff formatting Signed-off-by: Josh Loecker --- main/como/create_context_specific_model.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 1860745e..5a46ab13 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -178,10 +178,7 @@ def _build_with_fastcore(cobra_model, s_matrix, lower_bounds, upper_bounds, exp_ # 'Vlassis, Pacheco, Sauter (2014). Fast reconstruction of compact # context-specific metabolic network models. PLoS Comput. Biol. 10, # e1003424.' - logger.warning( - "Fastcore requires a flux consistant model is used as refererence, " - "to achieve this fastcc is required which is NOT reproducible." - ) + logger.warning("Fastcore requires a flux consistant model is used as refererence, to achieve this fastcc is required which is NOT reproducible.") logger.debug("Creating feasible model") incon_rxns, cobra_model = _feasibility_test(cobra_model, "other") properties = FastcoreProperties(core=exp_idx_list, solver=solver) @@ -358,7 +355,6 @@ async def _build_model( # noqa: C901 reference_model.objective = {getattr(reference_model.reactions, objective): 1} if objective not in force_reactions: force_reactions.append(objective) - reference_model = _set_boundaries(reference_model, boundary_reactions, lower_bounds, upper_bounds) reference_model.solver = solver.lower() @@ -587,9 +583,7 @@ async def create_context_specific_model( # noqa: C901 ): """Create a context-specific model using the provided data.""" _set_up_logging(level=log_level, location=log_location) - output_model_filepaths = ( - [output_model_filepaths] if isinstance(output_model_filepaths, Path) else output_model_filepaths - ) + output_model_filepaths = [output_model_filepaths] if isinstance(output_model_filepaths, Path) else output_model_filepaths for path in output_model_filepaths: if path.suffix not in {".mat", ".xml", ".sbml", ".json"}: _log_and_raise_error( From d6517004cc70dcf5d572130c452279f63c243134 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 3 Jun 2025 16:27:02 -0500 Subject: [PATCH 212/265] style: better variable naming Signed-off-by: Josh Loecker --- main/como/create_context_specific_model.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 5a46ab13..9e607c13 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -253,7 +253,7 @@ def _build_with_tinit( async def _map_expression_to_reaction( - model_cobra, + reference_model, gene_expression_file, recon_algorithm: Algorithm, low_thresh: float, @@ -277,7 +277,7 @@ async def _map_expression_to_reaction( # fmt: on error_count = 0 - for rxn in model_cobra.reactions: + for rxn in reference_model.reactions: rxn: cobra.Reaction gene_reaction_rule = _correct_bracket(rxn.gene_reaction_rule, rxn.gene_name_reaction_rule) if gene_reaction_rule == "": @@ -352,7 +352,6 @@ async def _build_model( # noqa: C901 level=LogLevel.ERROR, ) - reference_model.objective = {getattr(reference_model.reactions, objective): 1} if objective not in force_reactions: force_reactions.append(objective) reference_model = _set_boundaries(reference_model, boundary_reactions, lower_bounds, upper_bounds) From 66bc302a5b525600d627582b8a8ee53872e32b08 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 3 Jun 2025 16:27:21 -0500 Subject: [PATCH 213/265] refactor: fix creating evaluable gene reaction rules Signed-off-by: Josh Loecker --- main/como/create_context_specific_model.py | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 9e607c13..8818280e 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -279,31 +279,22 @@ async def _map_expression_to_reaction( error_count = 0 for rxn in reference_model.reactions: rxn: cobra.Reaction - gene_reaction_rule = _correct_bracket(rxn.gene_reaction_rule, rxn.gene_name_reaction_rule) + + gene_reaction_rule = rxn.gene_reaction_rule if gene_reaction_rule == "": continue - gene_ids = re.findall(r"\d+", gene_reaction_rule) + gene_ids = set(re.findall(r"\d+", gene_reaction_rule)) reaction_expression[rxn.id] = default_expression for gene_id in gene_ids: - activity = ( - f"{gene_activity.at[gene_id, 'active']}" - if gene_id in gene_activity.index - else f"{default_expression!s}" - ) + activity = f"{gene_activity.at[gene_id, 'active']}" if gene_id in gene_activity.index else f"{default_expression!s}" # replace gene_id with activity, using optional whitespace before and after the gene id # Do not replace the whitespace (if it exists) before and after the gene ID - gene_reaction_rule = re.sub( - pattern=rf"(? Date: Tue, 3 Jun 2025 16:27:37 -0500 Subject: [PATCH 214/265] style: ruff formatting Signed-off-by: Josh Loecker --- main/como/rnaseq_preprocess.py | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index aa4aaf32..332e9948 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -200,9 +200,7 @@ def _organize_gene_counts_files(data_dir: Path) -> list[_StudyMetrics]: count_files = list(gene_dir.glob("*.tab")) strand_files = list(strand_dir.glob("*.txt")) if len(count_files) == 0: - _log_and_raise_error( - f"No count files found for study '{gene_dir.stem}'.", error=ValueError, level=LogLevel.ERROR - ) + _log_and_raise_error(f"No count files found for study '{gene_dir.stem}'.", error=ValueError, level=LogLevel.ERROR) if len(strand_files) == 0: _log_and_raise_error( f"No strandedness files found for study '{gene_dir.stem}'.", @@ -330,9 +328,7 @@ async def _write_counts_matrix( ) -> pd.DataFrame: """Create a counts matrix file by reading gene counts table(s).""" study_metrics = _organize_gene_counts_files(data_dir=como_context_dir) - counts: list[pd.DataFrame] = await asyncio.gather( - *[_create_sample_counts_matrix(metric) for metric in study_metrics] - ) + counts: list[pd.DataFrame] = await asyncio.gather(*[_create_sample_counts_matrix(metric) for metric in study_metrics]) final_matrix = pd.DataFrame() for count in counts: @@ -666,13 +662,7 @@ async def read_counts(file: Path) -> list[str]: gene_info.at[i, "ensembl_gene_id"] = ensembl_ids gene_info.at[i, "size"] = end_pos - start_pos - gene_info = gene_info[ - ( - (gene_info["entrez_gene_id"] != "-") - & (gene_info["ensembl_gene_id"] != "-") - & (gene_info["gene_symbol"] != "-") - ) - ] + gene_info = gene_info[((gene_info["entrez_gene_id"] != "-") & (gene_info["ensembl_gene_id"] != "-") & (gene_info["gene_symbol"] != "-"))] gene_info.sort_values(by="ensembl_gene_id", inplace=True) gene_info.dropna(inplace=True) gene_info.to_csv(output_filepath, index=False) From 5e331ee9733fef067df0f3cedb8c620d0a9d3dcc Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 3 Jun 2025 16:27:58 -0500 Subject: [PATCH 215/265] refactor: only publish package when tag starts with 'v' Signed-off-by: Josh Loecker --- .github/workflows/container_build.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/container_build.yml b/.github/workflows/container_build.yml index 19512c76..f24b7152 100644 --- a/.github/workflows/container_build.yml +++ b/.github/workflows/container_build.yml @@ -11,8 +11,11 @@ env: jobs: build-and-push-image: + # IMPORTANT: Only run the publish job when a tag starting with 'v' is pushed + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') + name: Build and Push Docker Image - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest permissions: contents: read packages: write From f572104dcf0a893853a8b854b7c64065060934ff Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Thu, 7 Aug 2025 15:15:14 -0500 Subject: [PATCH 216/265] refactor: use better method of converting to numeric dtype Signed-off-by: Josh Loecker --- main/como/rnaseq_preprocess.py | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index 332e9948..b54c96f9 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -243,7 +243,7 @@ async def _process_first_multirun_sample(strand_file: Path, all_counts_files: li # Set na values to 0 sample_count = sample_count.fillna(value="0") - sample_count.iloc[:, 1:] = sample_count.iloc[:, 1:].apply(pd.to_numeric) + sample_count["counts"] = sample_count["counts"].astype(np.float64) count_sums: pd.DataFrame = pd.DataFrame(sample_count.sum(axis=1, numeric_only=True)) count_sums.insert(0, "ensembl_gene_id", sample_count["ensembl_gene_id"]) @@ -359,7 +359,7 @@ async def _create_config_df( # noqa: C901 The configuration file created is based on the gene counts matrix. If using zFPKM normalization technique, mean fragment lengths will be fetched """ - label_regex: Final = re.compile(r"(?PS\d{1,3})(?PR\d{1,3})(?:(?Pr\d{1,3}))?") + label_regex: Final = re.compile(r"(?PS\d{1,3})(?PR\d{1,3})(?Pr\d{1,3})?") gene_counts: list[Path] = list((como_context_dir / gene_count_dirname).rglob("*.tab")) if not gene_counts: _log_and_raise_error( @@ -621,6 +621,7 @@ async def _create_gene_info_file( """ async def read_counts(file: Path) -> list[str]: + print(f"Will read: '{file}'") data = await _read_file(file, h5ad_as_df=False) try: @@ -677,6 +678,7 @@ async def _process_como_input( rna: RNAType, ) -> None: config_df = await _create_config_df(context_name, como_context_dir=como_context_dir) + await _write_counts_matrix( config_df=config_df, como_context_dir=como_context_dir, @@ -796,3 +798,28 @@ async def rnaseq_preprocess( output_mrna_matrix_filepath=output_mrna_count_matrix_filepath, cache=cache, ) + + +async def _main(): + context_name = "notreatment" + taxon = 9606 + como_context_dir = Path("/Users/joshl/Projects/COMO/main/data/COMO_input/notreatment") + output_gene_info_filepath = Path("/Users/joshl/Projects/COMO/main/data/results/notreatment/gene_info.csv") + output_trna_metadata_filepath = Path("/Users/joshl/Projects/COMO/main/data/config_sheets/trna_config.xlsx") + output_trna_count_matrix_filepath = Path("/Users/joshl/Projects/COMO/main/data/results/notreatment/total-rna/totalrna_notreatment.csv") + + await rnaseq_preprocess( + context_name=context_name, + taxon=taxon, + como_context_dir=como_context_dir, + input_matrix_filepath=None, + output_gene_info_filepath=output_gene_info_filepath, + output_trna_metadata_filepath=output_trna_metadata_filepath, + output_trna_count_matrix_filepath=output_trna_count_matrix_filepath, + cache=False, + log_level="INFO", + ) + + +if __name__ == "__main__": + asyncio.run(_main()) From 3a547eac15d162a6b2fb01b421b5b9ff18be8c94 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 5 Sep 2025 11:14:10 -0500 Subject: [PATCH 217/265] chore: bump package requirements Signed-off-by: Josh Loecker --- pyproject.toml | 19 +- uv.lock | 3333 +++++++++++++++++++++++++++++------------------- 2 files changed, 2014 insertions(+), 1338 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index af0963d7..739f2d61 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,29 +5,30 @@ build-backend = "hatchling.build" [project] name = "COMO" dynamic = ["version"] -requires-python = ">=3.10,<3.13" +requires-python = ">=3.11,<3.14" dependencies = [ "aioftp>=0.23.1", + "anndata>=0.12.0", "cobamp@git+https://github.com/JoshLoecker/cobamp@master", "cobra>=0.28.0", "fast-bioservices>=0.3.9", - "kaleido==0.2.1", + "kaleido>=1.0.0", "loguru>=0.7.2", - "numpy<2.0", + "numpy>=2", "openpyxl>=3.1.5", "pandas>=1.3.5", "scanpy>=1.10.4", "scikit-learn>=1.5.2", - "scipy>=1.7.3", + "scipy>=1.13.0", "seaborn>=0.13.2", - "setuptools<60.0", - "statsmodels>=0.13.0", + "setuptools>=78.1.1", + "statsmodels>=0.13.0; python_version < '3.12'", "statsmodels>=0.14.0; python_version >= '3.12'", "troppo@git+https://github.com/JoshLoecker/troppo@master", ] [project.optional-dependencies] -gurobi = [ "gurobipy>=10.0.0" ] +gurobi = [ "gurobipy<14" ] interactive = [ "ipython>=8.0.0", "jupyterlab>=4.3.2" @@ -64,8 +65,12 @@ update_changelog_on_bump = true [tool.uv.sources] como = { workspace = true } +cobra = { git = "https://github.com/ripaul/cobrapy", rev = "hopsy-backend" } [dependency-groups] dev = [ "como", + "pandas-stubs>=2.3.2.250827", + "pre-commit>=4.2.0", + "scipy-stubs>=1.16.1.1", ] diff --git a/uv.lock b/uv.lock index 1a227653..e2c23f0c 100644 --- a/uv.lock +++ b/uv.lock @@ -1,139 +1,139 @@ version = 1 -requires-python = ">=3.10, <3.13" +revision = 2 +requires-python = ">=3.11, <3.14" resolution-markers = [ "python_full_version >= '3.12'", - "python_full_version == '3.11.*'", - "python_full_version < '3.11'", + "python_full_version < '3.12'", ] [[package]] name = "aiofiles" version = "24.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0b/03/a88171e277e8caa88a4c77808c20ebb04ba74cc4681bf1e9416c862de237/aiofiles-24.1.0.tar.gz", hash = "sha256:22a075c9e5a3810f0c2e48f3008c94d68c65d763b9b03857924c99e57355166c", size = 30247 } +sdist = { url = "https://files.pythonhosted.org/packages/0b/03/a88171e277e8caa88a4c77808c20ebb04ba74cc4681bf1e9416c862de237/aiofiles-24.1.0.tar.gz", hash = "sha256:22a075c9e5a3810f0c2e48f3008c94d68c65d763b9b03857924c99e57355166c", size = 30247, upload-time = "2024-06-24T11:02:03.584Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a5/45/30bb92d442636f570cb5651bc661f52b610e2eec3f891a5dc3a4c3667db0/aiofiles-24.1.0-py3-none-any.whl", hash = "sha256:b4ec55f4195e3eb5d7abd1bf7e061763e864dd4954231fb8539a0ef8bb8260e5", size = 15896 }, + { url = "https://files.pythonhosted.org/packages/a5/45/30bb92d442636f570cb5651bc661f52b610e2eec3f891a5dc3a4c3667db0/aiofiles-24.1.0-py3-none-any.whl", hash = "sha256:b4ec55f4195e3eb5d7abd1bf7e061763e864dd4954231fb8539a0ef8bb8260e5", size = 15896, upload-time = "2024-06-24T11:02:01.529Z" }, ] [[package]] name = "aioftp" -version = "0.23.1" +version = "0.26.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b5/be/8788b5ef25efb86261e4e69b5b21de472c6a5d39d06842dc5c5d19772506/aioftp-0.23.1.tar.gz", hash = "sha256:b80eadd8ca95d2bbbcfabe7de15cbe01ac117b2e7467717374de467bad93570b", size = 62481 } +sdist = { url = "https://files.pythonhosted.org/packages/df/0c/9cb5a5570af3b22ad188f63d5f6166da1344c9e720cda39e5de622114473/aioftp-0.26.2.tar.gz", hash = "sha256:ecd8cc9687bbb5e1b4dddc155aa1f3ea873d6e9f9e968221378daf04c2e4f763", size = 70140, upload-time = "2025-06-27T11:22:20.449Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/69/35104b809db2806da92cda96056efaed4cff8e069c1e8a23ec90787fa3f9/aioftp-0.23.1-py3-none-any.whl", hash = "sha256:62d1e59804afc7e42c57e8b3fa44e03e39630323cc666018a4e870d79dc58ec0", size = 37754 }, + { url = "https://files.pythonhosted.org/packages/05/e7/4921e957802495fcd2ce39cbf7b30338dd2250d2ecd3eb9de2077aa4b8fe/aioftp-0.26.2-py3-none-any.whl", hash = "sha256:c44d1de5e4b80b23eb2f5b45871e71e36e72cd623b06cc8ab9afd32873389105", size = 44393, upload-time = "2025-06-27T11:22:19.118Z" }, ] [[package]] name = "anndata" -version = "0.10.5.post1" +version = "0.12.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "array-api-compat" }, - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, { name = "h5py" }, + { name = "legacy-api-wrap" }, { name = "natsort" }, { name = "numpy" }, { name = "packaging" }, { name = "pandas" }, { name = "scipy" }, + { name = "zarr" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c1/40/8e8c3baca1b00f107cdd2f9b376bcf97de1a7912786b7b4012343228d143/anndata-0.10.5.post1.tar.gz", hash = "sha256:9a17c6eda9fc40759b3f5f81742f5d18c1a0a1acdf02f13e1646700ec082c155", size = 163852 } +sdist = { url = "https://files.pythonhosted.org/packages/b1/42/398550c2099e9017c0dbcead889910f09992367628fee8191446fdea3471/anndata-0.12.2.tar.gz", hash = "sha256:ecb3e0613585f5b464d0d3cfb0043a981b2eb92efaa90aae9042dd3e289c4a0a", size = 586312, upload-time = "2025-08-11T07:20:09.549Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/42/c7/23c2b5d3dd764650d235b574fdcac8d7252e6ae2f90273f65e95b9ca4e34/anndata-0.10.5.post1-py3-none-any.whl", hash = "sha256:3be9d5863d60d7a72d57a6e0392a3e7f3bb2bbfc79a038ddc53192a41517f5fc", size = 121004 }, + { url = "https://files.pythonhosted.org/packages/b9/03/d337cfd657f17678c61b9e8019a024e710cc8ff8a6792b5a3186388e9af4/anndata-0.12.2-py3-none-any.whl", hash = "sha256:aa3c28b77e53a004b584780ca76652aa51694ca2ad32d27ce22e07227254a62a", size = 169910, upload-time = "2025-08-11T07:20:07.622Z" }, ] [[package]] name = "annotated-types" version = "0.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 }, + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, ] [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.10.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, { name = "idna" }, { name = "sniffio" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9f/09/45b9b7a6d4e45c6bcb5bf61d19e3ab87df68e0601fa8c5293de3542546cc/anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c", size = 173422 } +sdist = { url = "https://files.pythonhosted.org/packages/f1/b4/636b3b65173d3ce9a38ef5f0522789614e590dab6a8d505340a4efe4c567/anyio-4.10.0.tar.gz", hash = "sha256:3f3fae35c96039744587aa5b8371e7e8e603c0702999535961dd336026973ba6", size = 213252, upload-time = "2025-08-04T08:54:26.451Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e4/f5/f2b75d2fc6f1a260f340f0e7c6a060f4dd2961cc16884ed851b0d18da06a/anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d", size = 90377 }, + { url = "https://files.pythonhosted.org/packages/6f/12/e5e0282d673bb9746bacfb6e2dba8719989d3660cdb2ea79aee9a9651afb/anyio-4.10.0-py3-none-any.whl", hash = "sha256:60e474ac86736bbfd6f210f7a61218939c318f43f9972497381f1c5e930ed3d1", size = 107213, upload-time = "2025-08-04T08:54:24.882Z" }, ] [[package]] name = "appdirs" version = "1.4.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d7/d8/05696357e0311f5b5c316d7b95f46c669dd9c15aaeecbb48c7d0aeb88c40/appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", size = 13470 } +sdist = { url = "https://files.pythonhosted.org/packages/d7/d8/05696357e0311f5b5c316d7b95f46c669dd9c15aaeecbb48c7d0aeb88c40/appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", size = 13470, upload-time = "2020-05-11T07:59:51.037Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3b/00/2344469e2084fb287c2e0b57b72910309874c3245463acd6cf5e3db69324/appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128", size = 9566 }, + { url = "https://files.pythonhosted.org/packages/3b/00/2344469e2084fb287c2e0b57b72910309874c3245463acd6cf5e3db69324/appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128", size = 9566, upload-time = "2020-05-11T07:59:49.499Z" }, ] [[package]] name = "appnope" version = "0.1.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/35/5d/752690df9ef5b76e169e68d6a129fa6d08a7100ca7f754c89495db3c6019/appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee", size = 4170 } +sdist = { url = "https://files.pythonhosted.org/packages/35/5d/752690df9ef5b76e169e68d6a129fa6d08a7100ca7f754c89495db3c6019/appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee", size = 4170, upload-time = "2024-02-06T09:43:11.258Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c", size = 4321 }, + { url = "https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c", size = 4321, upload-time = "2024-02-06T09:43:09.663Z" }, ] [[package]] name = "argcomplete" -version = "3.5.2" +version = "3.6.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7f/03/581b1c29d88fffaa08abbced2e628c34dd92d32f1adaed7e42fc416938b0/argcomplete-3.5.2.tar.gz", hash = "sha256:23146ed7ac4403b70bd6026402468942ceba34a6732255b9edf5b7354f68a6bb", size = 82341 } +sdist = { url = "https://files.pythonhosted.org/packages/16/0f/861e168fc813c56a78b35f3c30d91c6757d1fd185af1110f1aec784b35d0/argcomplete-3.6.2.tar.gz", hash = "sha256:d0519b1bc867f5f4f4713c41ad0aba73a4a5f007449716b16f385f2166dc6adf", size = 73403, upload-time = "2025-04-03T04:57:03.52Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a9/37/3fa718aaadd36e073891138dc3ebd919a71bafd4881c97d8a133265af191/argcomplete-3.5.2-py3-none-any.whl", hash = "sha256:036d020d79048a5d525bc63880d7a4b8d1668566b8a76daf1144c0bbe0f63472", size = 43506 }, + { url = "https://files.pythonhosted.org/packages/31/da/e42d7a9d8dd33fa775f467e4028a47936da2f01e4b0e561f9ba0d74cb0ca/argcomplete-3.6.2-py3-none-any.whl", hash = "sha256:65b3133a29ad53fb42c48cf5114752c7ab66c1c38544fdf6460f450c09b42591", size = 43708, upload-time = "2025-04-03T04:57:01.591Z" }, ] [[package]] name = "argon2-cffi" -version = "23.1.0" +version = "25.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "argon2-cffi-bindings" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/31/fa/57ec2c6d16ecd2ba0cf15f3c7d1c3c2e7b5fcb83555ff56d7ab10888ec8f/argon2_cffi-23.1.0.tar.gz", hash = "sha256:879c3e79a2729ce768ebb7d36d4609e3a78a4ca2ec3a9f12286ca057e3d0db08", size = 42798 } +sdist = { url = "https://files.pythonhosted.org/packages/0e/89/ce5af8a7d472a67cc819d5d998aa8c82c5d860608c4db9f46f1162d7dab9/argon2_cffi-25.1.0.tar.gz", hash = "sha256:694ae5cc8a42f4c4e2bf2ca0e64e51e23a040c6a517a85074683d3959e1346c1", size = 45706, upload-time = "2025-06-03T06:55:32.073Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a4/6a/e8a041599e78b6b3752da48000b14c8d1e8a04ded09c88c714ba047f34f5/argon2_cffi-23.1.0-py3-none-any.whl", hash = "sha256:c670642b78ba29641818ab2e68bd4e6a78ba53b7eff7b4c3815ae16abf91c7ea", size = 15124 }, + { url = "https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl", hash = "sha256:fdc8b074db390fccb6eb4a3604ae7231f219aa669a2652e0f20e16ba513d5741", size = 14657, upload-time = "2025-06-03T06:55:30.804Z" }, ] [[package]] name = "argon2-cffi-bindings" -version = "21.2.0" +version = "25.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b9/e9/184b8ccce6683b0aa2fbb7ba5683ea4b9c5763f1356347f1312c32e3c66e/argon2-cffi-bindings-21.2.0.tar.gz", hash = "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3", size = 1779911 } +sdist = { url = "https://files.pythonhosted.org/packages/5c/2d/db8af0df73c1cf454f71b2bbe5e356b8c1f8041c979f505b3d3186e520a9/argon2_cffi_bindings-25.1.0.tar.gz", hash = "sha256:b957f3e6ea4d55d820e40ff76f450952807013d361a65d7f28acc0acbf29229d", size = 1783441, upload-time = "2025-07-30T10:02:05.147Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d4/13/838ce2620025e9666aa8f686431f67a29052241692a3dd1ae9d3692a89d3/argon2_cffi_bindings-21.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367", size = 29658 }, - { url = "https://files.pythonhosted.org/packages/b3/02/f7f7bb6b6af6031edb11037639c697b912e1dea2db94d436e681aea2f495/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9524464572e12979364b7d600abf96181d3541da11e23ddf565a32e70bd4dc0d", size = 80583 }, - { url = "https://files.pythonhosted.org/packages/ec/f7/378254e6dd7ae6f31fe40c8649eea7d4832a42243acaf0f1fff9083b2bed/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b746dba803a79238e925d9046a63aa26bf86ab2a2fe74ce6b009a1c3f5c8f2ae", size = 86168 }, - { url = "https://files.pythonhosted.org/packages/74/f6/4a34a37a98311ed73bb80efe422fed95f2ac25a4cacc5ae1d7ae6a144505/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58ed19212051f49a523abb1dbe954337dc82d947fb6e5a0da60f7c8471a8476c", size = 82709 }, - { url = "https://files.pythonhosted.org/packages/74/2b/73d767bfdaab25484f7e7901379d5f8793cccbb86c6e0cbc4c1b96f63896/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:bd46088725ef7f58b5a1ef7ca06647ebaf0eb4baff7d1d0d177c6cc8744abd86", size = 83613 }, - { url = "https://files.pythonhosted.org/packages/4f/fd/37f86deef67ff57c76f137a67181949c2d408077e2e3dd70c6c42912c9bf/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_i686.whl", hash = "sha256:8cd69c07dd875537a824deec19f978e0f2078fdda07fd5c42ac29668dda5f40f", size = 84583 }, - { url = "https://files.pythonhosted.org/packages/6f/52/5a60085a3dae8fded8327a4f564223029f5f54b0cb0455a31131b5363a01/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f1152ac548bd5b8bcecfb0b0371f082037e47128653df2e8ba6e914d384f3c3e", size = 88475 }, - { url = "https://files.pythonhosted.org/packages/8b/95/143cd64feb24a15fa4b189a3e1e7efbaeeb00f39a51e99b26fc62fbacabd/argon2_cffi_bindings-21.2.0-cp36-abi3-win32.whl", hash = "sha256:603ca0aba86b1349b147cab91ae970c63118a0f30444d4bc80355937c950c082", size = 27698 }, - { url = "https://files.pythonhosted.org/packages/37/2c/e34e47c7dee97ba6f01a6203e0383e15b60fb85d78ac9a15cd066f6fe28b/argon2_cffi_bindings-21.2.0-cp36-abi3-win_amd64.whl", hash = "sha256:b2ef1c30440dbbcba7a5dc3e319408b59676e2e039e2ae11a8775ecf482b192f", size = 30817 }, - { url = "https://files.pythonhosted.org/packages/5a/e4/bf8034d25edaa495da3c8a3405627d2e35758e44ff6eaa7948092646fdcc/argon2_cffi_bindings-21.2.0-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e415e3f62c8d124ee16018e491a009937f8cf7ebf5eb430ffc5de21b900dad93", size = 53104 }, + { url = "https://files.pythonhosted.org/packages/1d/57/96b8b9f93166147826da5f90376e784a10582dd39a393c99bb62cfcf52f0/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:aecba1723ae35330a008418a91ea6cfcedf6d31e5fbaa056a166462ff066d500", size = 54121, upload-time = "2025-07-30T10:01:50.815Z" }, + { url = "https://files.pythonhosted.org/packages/0a/08/a9bebdb2e0e602dde230bdde8021b29f71f7841bd54801bcfd514acb5dcf/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2630b6240b495dfab90aebe159ff784d08ea999aa4b0d17efa734055a07d2f44", size = 29177, upload-time = "2025-07-30T10:01:51.681Z" }, + { url = "https://files.pythonhosted.org/packages/b6/02/d297943bcacf05e4f2a94ab6f462831dc20158614e5d067c35d4e63b9acb/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:7aef0c91e2c0fbca6fc68e7555aa60ef7008a739cbe045541e438373bc54d2b0", size = 31090, upload-time = "2025-07-30T10:01:53.184Z" }, + { url = "https://files.pythonhosted.org/packages/c1/93/44365f3d75053e53893ec6d733e4a5e3147502663554b4d864587c7828a7/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e021e87faa76ae0d413b619fe2b65ab9a037f24c60a1e6cc43457ae20de6dc6", size = 81246, upload-time = "2025-07-30T10:01:54.145Z" }, + { url = "https://files.pythonhosted.org/packages/09/52/94108adfdd6e2ddf58be64f959a0b9c7d4ef2fa71086c38356d22dc501ea/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d3e924cfc503018a714f94a49a149fdc0b644eaead5d1f089330399134fa028a", size = 87126, upload-time = "2025-07-30T10:01:55.074Z" }, + { url = "https://files.pythonhosted.org/packages/72/70/7a2993a12b0ffa2a9271259b79cc616e2389ed1a4d93842fac5a1f923ffd/argon2_cffi_bindings-25.1.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:c87b72589133f0346a1cb8d5ecca4b933e3c9b64656c9d175270a000e73b288d", size = 80343, upload-time = "2025-07-30T10:01:56.007Z" }, + { url = "https://files.pythonhosted.org/packages/78/9a/4e5157d893ffc712b74dbd868c7f62365618266982b64accab26bab01edc/argon2_cffi_bindings-25.1.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1db89609c06afa1a214a69a462ea741cf735b29a57530478c06eb81dd403de99", size = 86777, upload-time = "2025-07-30T10:01:56.943Z" }, + { url = "https://files.pythonhosted.org/packages/74/cd/15777dfde1c29d96de7f18edf4cc94c385646852e7c7b0320aa91ccca583/argon2_cffi_bindings-25.1.0-cp39-abi3-win32.whl", hash = "sha256:473bcb5f82924b1becbb637b63303ec8d10e84c8d241119419897a26116515d2", size = 27180, upload-time = "2025-07-30T10:01:57.759Z" }, + { url = "https://files.pythonhosted.org/packages/e2/c6/a759ece8f1829d1f162261226fbfd2c6832b3ff7657384045286d2afa384/argon2_cffi_bindings-25.1.0-cp39-abi3-win_amd64.whl", hash = "sha256:a98cd7d17e9f7ce244c0803cad3c23a7d379c301ba618a5fa76a67d116618b98", size = 31715, upload-time = "2025-07-30T10:01:58.56Z" }, + { url = "https://files.pythonhosted.org/packages/42/b9/f8d6fa329ab25128b7e98fd83a3cb34d9db5b059a9847eddb840a0af45dd/argon2_cffi_bindings-25.1.0-cp39-abi3-win_arm64.whl", hash = "sha256:b0fdbcf513833809c882823f98dc2f931cf659d9a1429616ac3adebb49f5db94", size = 27149, upload-time = "2025-07-30T10:01:59.329Z" }, ] [[package]] name = "array-api-compat" -version = "1.9" +version = "1.12.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e9/2c/3568b547cec656e717e5f3fe2b899c3ef052aef17c137c2c04635854c9c5/array_api_compat-1.9.tar.gz", hash = "sha256:8fb35f2895822b1cc6618449efd84aa76dcea1ab96940304f869663fd6a0dcd8", size = 42870 } +sdist = { url = "https://files.pythonhosted.org/packages/8d/bd/9fa5c7c5621698d5632cc852a79fbbdc28024462c9396698e5fdcb395f37/array_api_compat-1.12.0.tar.gz", hash = "sha256:585bc615f650de53ac24b7c012baecfcdd810f50df3573be47e6dd9fa20df974", size = 99883, upload-time = "2025-05-16T08:49:59.897Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/45/78/17985eac75d04c30f8cc375e4400e20b0787dc4a1c853a8fe9fad7932f55/array_api_compat-1.9-py3-none-any.whl", hash = "sha256:76db63c2d2461ba0e86b920c8b087f0a1617eb14de3ec29fe6811eeecad9c5e8", size = 49489 }, + { url = "https://files.pythonhosted.org/packages/e0/b1/0542e0cab6f49f151a2d7a42400f84f706fc0b64e85dc1f56708b2e9fd37/array_api_compat-1.12.0-py3-none-any.whl", hash = "sha256:a0b4795b6944a9507fde54679f9350e2ad2b1e2acf4a2408a098cdc27f890a8b", size = 58156, upload-time = "2025-05-16T08:49:58.129Z" }, ] [[package]] @@ -144,60 +144,79 @@ dependencies = [ { name = "python-dateutil" }, { name = "types-python-dateutil" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2e/00/0f6e8fcdb23ea632c866620cc872729ff43ed91d284c866b515c6342b173/arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85", size = 131960 } +sdist = { url = "https://files.pythonhosted.org/packages/2e/00/0f6e8fcdb23ea632c866620cc872729ff43ed91d284c866b515c6342b173/arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85", size = 131960, upload-time = "2023-09-30T22:11:18.25Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/ed/e97229a566617f2ae958a6b13e7cc0f585470eac730a73e9e82c32a3cdd2/arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80", size = 66419, upload-time = "2023-09-30T22:11:16.072Z" }, +] + +[[package]] +name = "arviz" +version = "0.22.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "h5netcdf" }, + { name = "matplotlib" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "pandas" }, + { name = "scipy" }, + { name = "setuptools" }, + { name = "typing-extensions" }, + { name = "xarray" }, + { name = "xarray-einstats" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/31/24/727d666e137f0b8c4a4fdc3dc91484ab2ed1206ac61733b2688efa85b5e7/arviz-0.22.0.tar.gz", hash = "sha256:d9df7592f1ce77ce69f7504dba13f8d550204c49c23e54849861dbcb2c640954", size = 1591019, upload-time = "2025-07-09T10:07:21.525Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f8/ed/e97229a566617f2ae958a6b13e7cc0f585470eac730a73e9e82c32a3cdd2/arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80", size = 66419 }, + { url = "https://files.pythonhosted.org/packages/81/38/5a3ee119be7f9f94f03a7626ee8edc52c9c9a9720cb020fa1f01fc87d4f2/arviz-0.22.0-py3-none-any.whl", hash = "sha256:336a3a4b1aa981997945f9ca104ca9f827e9c943f13760b18bf645ee5b12d56d", size = 1672062, upload-time = "2025-07-09T10:07:19.643Z" }, ] [[package]] name = "asttokens" version = "3.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4a/e7/82da0a03e7ba5141f05cce0d302e6eed121ae055e0456ca228bf693984bc/asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7", size = 61978 } +sdist = { url = "https://files.pythonhosted.org/packages/4a/e7/82da0a03e7ba5141f05cce0d302e6eed121ae055e0456ca228bf693984bc/asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7", size = 61978, upload-time = "2024-11-30T04:30:14.439Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/25/8a/c46dcc25341b5bce5472c718902eb3d38600a903b14fa6aeecef3f21a46f/asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2", size = 26918 }, + { url = "https://files.pythonhosted.org/packages/25/8a/c46dcc25341b5bce5472c718902eb3d38600a903b14fa6aeecef3f21a46f/asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2", size = 26918, upload-time = "2024-11-30T04:30:10.946Z" }, ] [[package]] name = "async-lru" -version = "2.0.4" +version = "2.0.5" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/80/e2/2b4651eff771f6fd900d233e175ddc5e2be502c7eb62c0c42f975c6d36cd/async-lru-2.0.4.tar.gz", hash = "sha256:b8a59a5df60805ff63220b2a0c5b5393da5521b113cd5465a44eb037d81a5627", size = 10019 } +sdist = { url = "https://files.pythonhosted.org/packages/b2/4d/71ec4d3939dc755264f680f6c2b4906423a304c3d18e96853f0a595dfe97/async_lru-2.0.5.tar.gz", hash = "sha256:481d52ccdd27275f42c43a928b4a50c3bfb2d67af4e78b170e3e0bb39c66e5bb", size = 10380, upload-time = "2025-03-16T17:25:36.919Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fa/9f/3c3503693386c4b0f245eaf5ca6198e3b28879ca0a40bde6b0e319793453/async_lru-2.0.4-py3-none-any.whl", hash = "sha256:ff02944ce3c288c5be660c42dbcca0742b32c3b279d6dceda655190240b99224", size = 6111 }, + { url = "https://files.pythonhosted.org/packages/03/49/d10027df9fce941cb8184e78a02857af36360d33e1721df81c5ed2179a1a/async_lru-2.0.5-py3-none-any.whl", hash = "sha256:ab95404d8d2605310d345932697371a5f40def0487c03d6d0ad9138de52c9943", size = 6069, upload-time = "2025-03-16T17:25:35.422Z" }, ] [[package]] name = "attrs" -version = "24.2.0" +version = "25.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fc/0f/aafca9af9315aee06a89ffde799a10a582fe8de76c563ee80bbcdc08b3fb/attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346", size = 792678 } +sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032, upload-time = "2025-03-13T11:10:22.779Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6a/21/5b6702a7f963e95456c0de2d495f67bf5fd62840ac655dc451586d23d39a/attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2", size = 63001 }, + { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload-time = "2025-03-13T11:10:21.14Z" }, ] [[package]] name = "babel" -version = "2.16.0" +version = "2.17.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2a/74/f1bc80f23eeba13393b7222b11d95ca3af2c1e28edca18af487137eefed9/babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316", size = 9348104 } +sdist = { url = "https://files.pythonhosted.org/packages/7d/6b/d52e42361e1aa00709585ecc30b3f9684b3ab62530771402248b1b1d6240/babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d", size = 9951852, upload-time = "2025-02-01T15:17:41.026Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ed/20/bc79bc575ba2e2a7f70e8a1155618bb1301eaa5132a8271373a6903f73f8/babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b", size = 9587599 }, + { url = "https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2", size = 10182537, upload-time = "2025-02-01T15:17:37.39Z" }, ] [[package]] name = "beautifulsoup4" -version = "4.12.3" +version = "4.13.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "soupsieve" }, + { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b3/ca/824b1195773ce6166d388573fc106ce56d4a805bd7427b624e063596ec58/beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051", size = 581181 } +sdist = { url = "https://files.pythonhosted.org/packages/85/2e/3e5079847e653b1f6dc647aa24549d68c6addb4c595cc0d902d1b19308ad/beautifulsoup4-4.13.5.tar.gz", hash = "sha256:5e70131382930e7c3de33450a2f54a63d5e4b19386eab43a5b34d594268f3695", size = 622954, upload-time = "2025-08-24T14:06:13.168Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/fe/e8c672695b37eecc5cbf43e1d0638d88d66ba3a44c4d321c796f4e59167f/beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed", size = 147925 }, + { url = "https://files.pythonhosted.org/packages/04/eb/f4151e0c7377a6e08a38108609ba5cede57986802757848688aeedd1b9e8/beautifulsoup4-4.13.5-py3-none-any.whl", hash = "sha256:642085eaa22233aceadff9c69651bc51e8bf3f874fb6d7104ece2beb24b47c4a", size = 105113, upload-time = "2025-08-24T14:06:14.884Z" }, ] [[package]] @@ -207,27 +226,32 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "webencodings" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/76/9a/0e33f5054c54d349ea62c277191c020c2d6ef1d65ab2cb1993f91ec846d1/bleach-6.2.0.tar.gz", hash = "sha256:123e894118b8a599fd80d3ec1a6d4cc7ce4e5882b1317a7e1ba69b56e95f991f", size = 203083 } +sdist = { url = "https://files.pythonhosted.org/packages/76/9a/0e33f5054c54d349ea62c277191c020c2d6ef1d65ab2cb1993f91ec846d1/bleach-6.2.0.tar.gz", hash = "sha256:123e894118b8a599fd80d3ec1a6d4cc7ce4e5882b1317a7e1ba69b56e95f991f", size = 203083, upload-time = "2024-10-29T18:30:40.477Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fc/55/96142937f66150805c25c4d0f31ee4132fd33497753400734f9dfdcbdc66/bleach-6.2.0-py3-none-any.whl", hash = "sha256:117d9c6097a7c3d22fd578fcd8d35ff1e125df6736f554da4e432fdd63f31e5e", size = 163406 }, + { url = "https://files.pythonhosted.org/packages/fc/55/96142937f66150805c25c4d0f31ee4132fd33497753400734f9dfdcbdc66/bleach-6.2.0-py3-none-any.whl", hash = "sha256:117d9c6097a7c3d22fd578fcd8d35ff1e125df6736f554da4e432fdd63f31e5e", size = 163406, upload-time = "2024-10-29T18:30:38.186Z" }, +] + +[package.optional-dependencies] +css = [ + { name = "tinycss2" }, ] [[package]] name = "boolean-py" -version = "4.0" +version = "5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/d9/b6e56a303d221fc0bdff2c775e4eef7fedd58194aa5a96fa89fb71634cc9/boolean.py-4.0.tar.gz", hash = "sha256:17b9a181630e43dde1851d42bef546d616d5d9b4480357514597e78b203d06e4", size = 34504 } +sdist = { url = "https://files.pythonhosted.org/packages/c4/cf/85379f13b76f3a69bca86b60237978af17d6aa0bc5998978c3b8cf05abb2/boolean_py-5.0.tar.gz", hash = "sha256:60cbc4bad079753721d32649545505362c754e121570ada4658b852a3a318d95", size = 37047, upload-time = "2025-04-03T10:39:49.734Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3f/02/6389ef0529af6da0b913374dedb9bbde8eabfe45767ceec38cc37801b0bd/boolean.py-4.0-py3-none-any.whl", hash = "sha256:2876f2051d7d6394a531d82dc6eb407faa0b01a0a0b3083817ccd7323b8d96bd", size = 25909 }, + { url = "https://files.pythonhosted.org/packages/e5/ca/78d423b324b8d77900030fa59c4aa9054261ef0925631cd2501dd015b7b7/boolean_py-5.0-py3-none-any.whl", hash = "sha256:ef28a70bd43115208441b53a045d1549e2f0ec6e3d08a9d142cbc41c1938e8d9", size = 26577, upload-time = "2025-04-03T10:39:48.449Z" }, ] [[package]] name = "certifi" -version = "2024.8.30" +version = "2025.8.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b0/ee/9b19140fe824b367c04c5e1b369942dd754c4c5462d5674002f75c4dedc1/certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9", size = 168507 } +sdist = { url = "https://files.pythonhosted.org/packages/dc/67/960ebe6bf230a96cda2e0abcf73af550ec4f090005363542f0765df162e0/certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407", size = 162386, upload-time = "2025-08-03T03:07:47.08Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", size = 167321 }, + { url = "https://files.pythonhosted.org/packages/e5/48/1549795ba7742c948d2ad169c1c8cdbae65bc450d6cd753d124b17c8cd32/certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5", size = 161216, upload-time = "2025-08-03T03:07:45.777Z" }, ] [[package]] @@ -237,97 +261,106 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pycparser" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/90/07/f44ca684db4e4f08a3fdc6eeb9a0d15dc6883efc7b8c90357fdbf74e186c/cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14", size = 182191 }, - { url = "https://files.pythonhosted.org/packages/08/fd/cc2fedbd887223f9f5d170c96e57cbf655df9831a6546c1727ae13fa977a/cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67", size = 178592 }, - { url = "https://files.pythonhosted.org/packages/de/cc/4635c320081c78d6ffc2cab0a76025b691a91204f4aa317d568ff9280a2d/cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382", size = 426024 }, - { url = "https://files.pythonhosted.org/packages/b6/7b/3b2b250f3aab91abe5f8a51ada1b717935fdaec53f790ad4100fe2ec64d1/cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702", size = 448188 }, - { url = "https://files.pythonhosted.org/packages/d3/48/1b9283ebbf0ec065148d8de05d647a986c5f22586b18120020452fff8f5d/cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3", size = 455571 }, - { url = "https://files.pythonhosted.org/packages/40/87/3b8452525437b40f39ca7ff70276679772ee7e8b394934ff60e63b7b090c/cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6", size = 436687 }, - { url = "https://files.pythonhosted.org/packages/8d/fb/4da72871d177d63649ac449aec2e8a29efe0274035880c7af59101ca2232/cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17", size = 446211 }, - { url = "https://files.pythonhosted.org/packages/ab/a0/62f00bcb411332106c02b663b26f3545a9ef136f80d5df746c05878f8c4b/cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8", size = 461325 }, - { url = "https://files.pythonhosted.org/packages/36/83/76127035ed2e7e27b0787604d99da630ac3123bfb02d8e80c633f218a11d/cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e", size = 438784 }, - { url = "https://files.pythonhosted.org/packages/21/81/a6cd025db2f08ac88b901b745c163d884641909641f9b826e8cb87645942/cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be", size = 461564 }, - { url = "https://files.pythonhosted.org/packages/f8/fe/4d41c2f200c4a457933dbd98d3cf4e911870877bd94d9656cc0fcb390681/cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c", size = 171804 }, - { url = "https://files.pythonhosted.org/packages/d1/b6/0b0f5ab93b0df4acc49cae758c81fe4e5ef26c3ae2e10cc69249dfd8b3ab/cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15", size = 181299 }, - { url = "https://files.pythonhosted.org/packages/6b/f4/927e3a8899e52a27fa57a48607ff7dc91a9ebe97399b357b85a0c7892e00/cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401", size = 182264 }, - { url = "https://files.pythonhosted.org/packages/6c/f5/6c3a8efe5f503175aaddcbea6ad0d2c96dad6f5abb205750d1b3df44ef29/cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf", size = 178651 }, - { url = "https://files.pythonhosted.org/packages/94/dd/a3f0118e688d1b1a57553da23b16bdade96d2f9bcda4d32e7d2838047ff7/cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4", size = 445259 }, - { url = "https://files.pythonhosted.org/packages/2e/ea/70ce63780f096e16ce8588efe039d3c4f91deb1dc01e9c73a287939c79a6/cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", size = 469200 }, - { url = "https://files.pythonhosted.org/packages/1c/a0/a4fa9f4f781bda074c3ddd57a572b060fa0df7655d2a4247bbe277200146/cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", size = 477235 }, - { url = "https://files.pythonhosted.org/packages/62/12/ce8710b5b8affbcdd5c6e367217c242524ad17a02fe5beec3ee339f69f85/cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", size = 459721 }, - { url = "https://files.pythonhosted.org/packages/ff/6b/d45873c5e0242196f042d555526f92aa9e0c32355a1be1ff8c27f077fd37/cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", size = 467242 }, - { url = "https://files.pythonhosted.org/packages/1a/52/d9a0e523a572fbccf2955f5abe883cfa8bcc570d7faeee06336fbd50c9fc/cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", size = 477999 }, - { url = "https://files.pythonhosted.org/packages/44/74/f2a2460684a1a2d00ca799ad880d54652841a780c4c97b87754f660c7603/cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f", size = 454242 }, - { url = "https://files.pythonhosted.org/packages/f8/4a/34599cac7dfcd888ff54e801afe06a19c17787dfd94495ab0c8d35fe99fb/cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b", size = 478604 }, - { url = "https://files.pythonhosted.org/packages/34/33/e1b8a1ba29025adbdcda5fb3a36f94c03d771c1b7b12f726ff7fef2ebe36/cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655", size = 171727 }, - { url = "https://files.pythonhosted.org/packages/3d/97/50228be003bb2802627d28ec0627837ac0bf35c90cf769812056f235b2d1/cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0", size = 181400 }, - { url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178 }, - { url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840 }, - { url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803 }, - { url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850 }, - { url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729 }, - { url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256 }, - { url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424 }, - { url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568 }, - { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736 }, - { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448 }, - { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976 }, +sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621, upload-time = "2024-09-04T20:45:21.852Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6b/f4/927e3a8899e52a27fa57a48607ff7dc91a9ebe97399b357b85a0c7892e00/cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401", size = 182264, upload-time = "2024-09-04T20:43:51.124Z" }, + { url = "https://files.pythonhosted.org/packages/6c/f5/6c3a8efe5f503175aaddcbea6ad0d2c96dad6f5abb205750d1b3df44ef29/cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf", size = 178651, upload-time = "2024-09-04T20:43:52.872Z" }, + { url = "https://files.pythonhosted.org/packages/94/dd/a3f0118e688d1b1a57553da23b16bdade96d2f9bcda4d32e7d2838047ff7/cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4", size = 445259, upload-time = "2024-09-04T20:43:56.123Z" }, + { url = "https://files.pythonhosted.org/packages/2e/ea/70ce63780f096e16ce8588efe039d3c4f91deb1dc01e9c73a287939c79a6/cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", size = 469200, upload-time = "2024-09-04T20:43:57.891Z" }, + { url = "https://files.pythonhosted.org/packages/1c/a0/a4fa9f4f781bda074c3ddd57a572b060fa0df7655d2a4247bbe277200146/cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", size = 477235, upload-time = "2024-09-04T20:44:00.18Z" }, + { url = "https://files.pythonhosted.org/packages/62/12/ce8710b5b8affbcdd5c6e367217c242524ad17a02fe5beec3ee339f69f85/cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", size = 459721, upload-time = "2024-09-04T20:44:01.585Z" }, + { url = "https://files.pythonhosted.org/packages/ff/6b/d45873c5e0242196f042d555526f92aa9e0c32355a1be1ff8c27f077fd37/cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", size = 467242, upload-time = "2024-09-04T20:44:03.467Z" }, + { url = "https://files.pythonhosted.org/packages/1a/52/d9a0e523a572fbccf2955f5abe883cfa8bcc570d7faeee06336fbd50c9fc/cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", size = 477999, upload-time = "2024-09-04T20:44:05.023Z" }, + { url = "https://files.pythonhosted.org/packages/44/74/f2a2460684a1a2d00ca799ad880d54652841a780c4c97b87754f660c7603/cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f", size = 454242, upload-time = "2024-09-04T20:44:06.444Z" }, + { url = "https://files.pythonhosted.org/packages/f8/4a/34599cac7dfcd888ff54e801afe06a19c17787dfd94495ab0c8d35fe99fb/cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b", size = 478604, upload-time = "2024-09-04T20:44:08.206Z" }, + { url = "https://files.pythonhosted.org/packages/34/33/e1b8a1ba29025adbdcda5fb3a36f94c03d771c1b7b12f726ff7fef2ebe36/cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655", size = 171727, upload-time = "2024-09-04T20:44:09.481Z" }, + { url = "https://files.pythonhosted.org/packages/3d/97/50228be003bb2802627d28ec0627837ac0bf35c90cf769812056f235b2d1/cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0", size = 181400, upload-time = "2024-09-04T20:44:10.873Z" }, + { url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178, upload-time = "2024-09-04T20:44:12.232Z" }, + { url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840, upload-time = "2024-09-04T20:44:13.739Z" }, + { url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803, upload-time = "2024-09-04T20:44:15.231Z" }, + { url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850, upload-time = "2024-09-04T20:44:17.188Z" }, + { url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729, upload-time = "2024-09-04T20:44:18.688Z" }, + { url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256, upload-time = "2024-09-04T20:44:20.248Z" }, + { url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424, upload-time = "2024-09-04T20:44:21.673Z" }, + { url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568, upload-time = "2024-09-04T20:44:23.245Z" }, + { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736, upload-time = "2024-09-04T20:44:24.757Z" }, + { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448, upload-time = "2024-09-04T20:44:26.208Z" }, + { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976, upload-time = "2024-09-04T20:44:27.578Z" }, + { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989, upload-time = "2024-09-04T20:44:28.956Z" }, + { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802, upload-time = "2024-09-04T20:44:30.289Z" }, + { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792, upload-time = "2024-09-04T20:44:32.01Z" }, + { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893, upload-time = "2024-09-04T20:44:33.606Z" }, + { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810, upload-time = "2024-09-04T20:44:35.191Z" }, + { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200, upload-time = "2024-09-04T20:44:36.743Z" }, + { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447, upload-time = "2024-09-04T20:44:38.492Z" }, + { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358, upload-time = "2024-09-04T20:44:40.046Z" }, + { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469, upload-time = "2024-09-04T20:44:41.616Z" }, + { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475, upload-time = "2024-09-04T20:44:43.733Z" }, + { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009, upload-time = "2024-09-04T20:44:45.309Z" }, +] + +[[package]] +name = "cfgv" +version = "3.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/11/74/539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560", size = 7114, upload-time = "2023-08-12T20:38:17.776Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249, upload-time = "2023-08-12T20:38:16.269Z" }, ] [[package]] name = "charset-normalizer" -version = "3.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f2/4f/e1808dc01273379acc506d18f1504eb2d299bd4131743b9fc54d7be4df1e/charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", size = 106620 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/69/8b/825cc84cf13a28bfbcba7c416ec22bf85a9584971be15b21dd8300c65b7f/charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6", size = 196363 }, - { url = "https://files.pythonhosted.org/packages/23/81/d7eef6a99e42c77f444fdd7bc894b0ceca6c3a95c51239e74a722039521c/charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b", size = 125639 }, - { url = "https://files.pythonhosted.org/packages/21/67/b4564d81f48042f520c948abac7079356e94b30cb8ffb22e747532cf469d/charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99", size = 120451 }, - { url = "https://files.pythonhosted.org/packages/c2/72/12a7f0943dd71fb5b4e7b55c41327ac0a1663046a868ee4d0d8e9c369b85/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca", size = 140041 }, - { url = "https://files.pythonhosted.org/packages/67/56/fa28c2c3e31217c4c52158537a2cf5d98a6c1e89d31faf476c89391cd16b/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d", size = 150333 }, - { url = "https://files.pythonhosted.org/packages/f9/d2/466a9be1f32d89eb1554cf84073a5ed9262047acee1ab39cbaefc19635d2/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7", size = 142921 }, - { url = "https://files.pythonhosted.org/packages/f8/01/344ec40cf5d85c1da3c1f57566c59e0c9b56bcc5566c08804a95a6cc8257/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3", size = 144785 }, - { url = "https://files.pythonhosted.org/packages/73/8b/2102692cb6d7e9f03b9a33a710e0164cadfce312872e3efc7cfe22ed26b4/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907", size = 146631 }, - { url = "https://files.pythonhosted.org/packages/d8/96/cc2c1b5d994119ce9f088a9a0c3ebd489d360a2eb058e2c8049f27092847/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b", size = 140867 }, - { url = "https://files.pythonhosted.org/packages/c9/27/cde291783715b8ec30a61c810d0120411844bc4c23b50189b81188b273db/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912", size = 149273 }, - { url = "https://files.pythonhosted.org/packages/3a/a4/8633b0fc1a2d1834d5393dafecce4a1cc56727bfd82b4dc18fc92f0d3cc3/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95", size = 152437 }, - { url = "https://files.pythonhosted.org/packages/64/ea/69af161062166b5975ccbb0961fd2384853190c70786f288684490913bf5/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e", size = 150087 }, - { url = "https://files.pythonhosted.org/packages/3b/fd/e60a9d9fd967f4ad5a92810138192f825d77b4fa2a557990fd575a47695b/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe", size = 145142 }, - { url = "https://files.pythonhosted.org/packages/6d/02/8cb0988a1e49ac9ce2eed1e07b77ff118f2923e9ebd0ede41ba85f2dcb04/charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc", size = 94701 }, - { url = "https://files.pythonhosted.org/packages/d6/20/f1d4670a8a723c46be695dff449d86d6092916f9e99c53051954ee33a1bc/charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749", size = 102191 }, - { url = "https://files.pythonhosted.org/packages/9c/61/73589dcc7a719582bf56aae309b6103d2762b526bffe189d635a7fcfd998/charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", size = 193339 }, - { url = "https://files.pythonhosted.org/packages/77/d5/8c982d58144de49f59571f940e329ad6e8615e1e82ef84584c5eeb5e1d72/charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", size = 124366 }, - { url = "https://files.pythonhosted.org/packages/bf/19/411a64f01ee971bed3231111b69eb56f9331a769072de479eae7de52296d/charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", size = 118874 }, - { url = "https://files.pythonhosted.org/packages/4c/92/97509850f0d00e9f14a46bc751daabd0ad7765cff29cdfb66c68b6dad57f/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", size = 138243 }, - { url = "https://files.pythonhosted.org/packages/e2/29/d227805bff72ed6d6cb1ce08eec707f7cfbd9868044893617eb331f16295/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", size = 148676 }, - { url = "https://files.pythonhosted.org/packages/13/bc/87c2c9f2c144bedfa62f894c3007cd4530ba4b5351acb10dc786428a50f0/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", size = 141289 }, - { url = "https://files.pythonhosted.org/packages/eb/5b/6f10bad0f6461fa272bfbbdf5d0023b5fb9bc6217c92bf068fa5a99820f5/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", size = 142585 }, - { url = "https://files.pythonhosted.org/packages/3b/a0/a68980ab8a1f45a36d9745d35049c1af57d27255eff8c907e3add84cf68f/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5", size = 144408 }, - { url = "https://files.pythonhosted.org/packages/d7/a1/493919799446464ed0299c8eef3c3fad0daf1c3cd48bff9263c731b0d9e2/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", size = 139076 }, - { url = "https://files.pythonhosted.org/packages/fb/9d/9c13753a5a6e0db4a0a6edb1cef7aee39859177b64e1a1e748a6e3ba62c2/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c", size = 146874 }, - { url = "https://files.pythonhosted.org/packages/75/d2/0ab54463d3410709c09266dfb416d032a08f97fd7d60e94b8c6ef54ae14b/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", size = 150871 }, - { url = "https://files.pythonhosted.org/packages/8d/c9/27e41d481557be53d51e60750b85aa40eaf52b841946b3cdeff363105737/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", size = 148546 }, - { url = "https://files.pythonhosted.org/packages/ee/44/4f62042ca8cdc0cabf87c0fc00ae27cd8b53ab68be3605ba6d071f742ad3/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", size = 143048 }, - { url = "https://files.pythonhosted.org/packages/01/f8/38842422988b795220eb8038745d27a675ce066e2ada79516c118f291f07/charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99", size = 94389 }, - { url = "https://files.pythonhosted.org/packages/0b/6e/b13bd47fa9023b3699e94abf565b5a2f0b0be6e9ddac9812182596ee62e4/charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27", size = 101752 }, - { url = "https://files.pythonhosted.org/packages/d3/0b/4b7a70987abf9b8196845806198975b6aab4ce016632f817ad758a5aa056/charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6", size = 194445 }, - { url = "https://files.pythonhosted.org/packages/50/89/354cc56cf4dd2449715bc9a0f54f3aef3dc700d2d62d1fa5bbea53b13426/charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf", size = 125275 }, - { url = "https://files.pythonhosted.org/packages/fa/44/b730e2a2580110ced837ac083d8ad222343c96bb6b66e9e4e706e4d0b6df/charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db", size = 119020 }, - { url = "https://files.pythonhosted.org/packages/9d/e4/9263b8240ed9472a2ae7ddc3e516e71ef46617fe40eaa51221ccd4ad9a27/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1", size = 139128 }, - { url = "https://files.pythonhosted.org/packages/6b/e3/9f73e779315a54334240353eaea75854a9a690f3f580e4bd85d977cb2204/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03", size = 149277 }, - { url = "https://files.pythonhosted.org/packages/1a/cf/f1f50c2f295312edb8a548d3fa56a5c923b146cd3f24114d5adb7e7be558/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284", size = 142174 }, - { url = "https://files.pythonhosted.org/packages/16/92/92a76dc2ff3a12e69ba94e7e05168d37d0345fa08c87e1fe24d0c2a42223/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15", size = 143838 }, - { url = "https://files.pythonhosted.org/packages/a4/01/2117ff2b1dfc61695daf2babe4a874bca328489afa85952440b59819e9d7/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8", size = 146149 }, - { url = "https://files.pythonhosted.org/packages/f6/9b/93a332b8d25b347f6839ca0a61b7f0287b0930216994e8bf67a75d050255/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2", size = 140043 }, - { url = "https://files.pythonhosted.org/packages/ab/f6/7ac4a01adcdecbc7a7587767c776d53d369b8b971382b91211489535acf0/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719", size = 148229 }, - { url = "https://files.pythonhosted.org/packages/9d/be/5708ad18161dee7dc6a0f7e6cf3a88ea6279c3e8484844c0590e50e803ef/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631", size = 151556 }, - { url = "https://files.pythonhosted.org/packages/5a/bb/3d8bc22bacb9eb89785e83e6723f9888265f3a0de3b9ce724d66bd49884e/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b", size = 149772 }, - { url = "https://files.pythonhosted.org/packages/f7/fa/d3fc622de05a86f30beea5fc4e9ac46aead4731e73fd9055496732bcc0a4/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565", size = 144800 }, - { url = "https://files.pythonhosted.org/packages/9a/65/bdb9bc496d7d190d725e96816e20e2ae3a6fa42a5cac99c3c3d6ff884118/charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7", size = 94836 }, - { url = "https://files.pythonhosted.org/packages/3e/67/7b72b69d25b89c0b3cea583ee372c43aa24df15f0e0f8d3982c57804984b/charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9", size = 102187 }, - { url = "https://files.pythonhosted.org/packages/bf/9b/08c0432272d77b04803958a4598a51e2a4b51c06640af8b8f0f908c18bf2/charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", size = 49446 }, +version = "3.4.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/83/2d/5fd176ceb9b2fc619e63405525573493ca23441330fcdaee6bef9460e924/charset_normalizer-3.4.3.tar.gz", hash = "sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14", size = 122371, upload-time = "2025-08-09T07:57:28.46Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/b5/991245018615474a60965a7c9cd2b4efbaabd16d582a5547c47ee1c7730b/charset_normalizer-3.4.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b256ee2e749283ef3ddcff51a675ff43798d92d746d1a6e4631bf8c707d22d0b", size = 204483, upload-time = "2025-08-09T07:55:53.12Z" }, + { url = "https://files.pythonhosted.org/packages/c7/2a/ae245c41c06299ec18262825c1569c5d3298fc920e4ddf56ab011b417efd/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:13faeacfe61784e2559e690fc53fa4c5ae97c6fcedb8eb6fb8d0a15b475d2c64", size = 145520, upload-time = "2025-08-09T07:55:54.712Z" }, + { url = "https://files.pythonhosted.org/packages/3a/a4/b3b6c76e7a635748c4421d2b92c7b8f90a432f98bda5082049af37ffc8e3/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:00237675befef519d9af72169d8604a067d92755e84fe76492fef5441db05b91", size = 158876, upload-time = "2025-08-09T07:55:56.024Z" }, + { url = "https://files.pythonhosted.org/packages/e2/e6/63bb0e10f90a8243c5def74b5b105b3bbbfb3e7bb753915fe333fb0c11ea/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:585f3b2a80fbd26b048a0be90c5aae8f06605d3c92615911c3a2b03a8a3b796f", size = 156083, upload-time = "2025-08-09T07:55:57.582Z" }, + { url = "https://files.pythonhosted.org/packages/87/df/b7737ff046c974b183ea9aa111b74185ac8c3a326c6262d413bd5a1b8c69/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e78314bdc32fa80696f72fa16dc61168fda4d6a0c014e0380f9d02f0e5d8a07", size = 150295, upload-time = "2025-08-09T07:55:59.147Z" }, + { url = "https://files.pythonhosted.org/packages/61/f1/190d9977e0084d3f1dc169acd060d479bbbc71b90bf3e7bf7b9927dec3eb/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:96b2b3d1a83ad55310de8c7b4a2d04d9277d5591f40761274856635acc5fcb30", size = 148379, upload-time = "2025-08-09T07:56:00.364Z" }, + { url = "https://files.pythonhosted.org/packages/4c/92/27dbe365d34c68cfe0ca76f1edd70e8705d82b378cb54ebbaeabc2e3029d/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:939578d9d8fd4299220161fdd76e86c6a251987476f5243e8864a7844476ba14", size = 160018, upload-time = "2025-08-09T07:56:01.678Z" }, + { url = "https://files.pythonhosted.org/packages/99/04/baae2a1ea1893a01635d475b9261c889a18fd48393634b6270827869fa34/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:fd10de089bcdcd1be95a2f73dbe6254798ec1bda9f450d5828c96f93e2536b9c", size = 157430, upload-time = "2025-08-09T07:56:02.87Z" }, + { url = "https://files.pythonhosted.org/packages/2f/36/77da9c6a328c54d17b960c89eccacfab8271fdaaa228305330915b88afa9/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1e8ac75d72fa3775e0b7cb7e4629cec13b7514d928d15ef8ea06bca03ef01cae", size = 151600, upload-time = "2025-08-09T07:56:04.089Z" }, + { url = "https://files.pythonhosted.org/packages/64/d4/9eb4ff2c167edbbf08cdd28e19078bf195762e9bd63371689cab5ecd3d0d/charset_normalizer-3.4.3-cp311-cp311-win32.whl", hash = "sha256:6cf8fd4c04756b6b60146d98cd8a77d0cdae0e1ca20329da2ac85eed779b6849", size = 99616, upload-time = "2025-08-09T07:56:05.658Z" }, + { url = "https://files.pythonhosted.org/packages/f4/9c/996a4a028222e7761a96634d1820de8a744ff4327a00ada9c8942033089b/charset_normalizer-3.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:31a9a6f775f9bcd865d88ee350f0ffb0e25936a7f930ca98995c05abf1faf21c", size = 107108, upload-time = "2025-08-09T07:56:07.176Z" }, + { url = "https://files.pythonhosted.org/packages/e9/5e/14c94999e418d9b87682734589404a25854d5f5d0408df68bc15b6ff54bb/charset_normalizer-3.4.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1", size = 205655, upload-time = "2025-08-09T07:56:08.475Z" }, + { url = "https://files.pythonhosted.org/packages/7d/a8/c6ec5d389672521f644505a257f50544c074cf5fc292d5390331cd6fc9c3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884", size = 146223, upload-time = "2025-08-09T07:56:09.708Z" }, + { url = "https://files.pythonhosted.org/packages/fc/eb/a2ffb08547f4e1e5415fb69eb7db25932c52a52bed371429648db4d84fb1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018", size = 159366, upload-time = "2025-08-09T07:56:11.326Z" }, + { url = "https://files.pythonhosted.org/packages/82/10/0fd19f20c624b278dddaf83b8464dcddc2456cb4b02bb902a6da126b87a1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392", size = 157104, upload-time = "2025-08-09T07:56:13.014Z" }, + { url = "https://files.pythonhosted.org/packages/16/ab/0233c3231af734f5dfcf0844aa9582d5a1466c985bbed6cedab85af9bfe3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f", size = 151830, upload-time = "2025-08-09T07:56:14.428Z" }, + { url = "https://files.pythonhosted.org/packages/ae/02/e29e22b4e02839a0e4a06557b1999d0a47db3567e82989b5bb21f3fbbd9f/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154", size = 148854, upload-time = "2025-08-09T07:56:16.051Z" }, + { url = "https://files.pythonhosted.org/packages/05/6b/e2539a0a4be302b481e8cafb5af8792da8093b486885a1ae4d15d452bcec/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491", size = 160670, upload-time = "2025-08-09T07:56:17.314Z" }, + { url = "https://files.pythonhosted.org/packages/31/e7/883ee5676a2ef217a40ce0bffcc3d0dfbf9e64cbcfbdf822c52981c3304b/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93", size = 158501, upload-time = "2025-08-09T07:56:18.641Z" }, + { url = "https://files.pythonhosted.org/packages/c1/35/6525b21aa0db614cf8b5792d232021dca3df7f90a1944db934efa5d20bb1/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f", size = 153173, upload-time = "2025-08-09T07:56:20.289Z" }, + { url = "https://files.pythonhosted.org/packages/50/ee/f4704bad8201de513fdc8aac1cabc87e38c5818c93857140e06e772b5892/charset_normalizer-3.4.3-cp312-cp312-win32.whl", hash = "sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37", size = 99822, upload-time = "2025-08-09T07:56:21.551Z" }, + { url = "https://files.pythonhosted.org/packages/39/f5/3b3836ca6064d0992c58c7561c6b6eee1b3892e9665d650c803bd5614522/charset_normalizer-3.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc", size = 107543, upload-time = "2025-08-09T07:56:23.115Z" }, + { url = "https://files.pythonhosted.org/packages/65/ca/2135ac97709b400c7654b4b764daf5c5567c2da45a30cdd20f9eefe2d658/charset_normalizer-3.4.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe", size = 205326, upload-time = "2025-08-09T07:56:24.721Z" }, + { url = "https://files.pythonhosted.org/packages/71/11/98a04c3c97dd34e49c7d247083af03645ca3730809a5509443f3c37f7c99/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8", size = 146008, upload-time = "2025-08-09T07:56:26.004Z" }, + { url = "https://files.pythonhosted.org/packages/60/f5/4659a4cb3c4ec146bec80c32d8bb16033752574c20b1252ee842a95d1a1e/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9", size = 159196, upload-time = "2025-08-09T07:56:27.25Z" }, + { url = "https://files.pythonhosted.org/packages/86/9e/f552f7a00611f168b9a5865a1414179b2c6de8235a4fa40189f6f79a1753/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31", size = 156819, upload-time = "2025-08-09T07:56:28.515Z" }, + { url = "https://files.pythonhosted.org/packages/7e/95/42aa2156235cbc8fa61208aded06ef46111c4d3f0de233107b3f38631803/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f", size = 151350, upload-time = "2025-08-09T07:56:29.716Z" }, + { url = "https://files.pythonhosted.org/packages/c2/a9/3865b02c56f300a6f94fc631ef54f0a8a29da74fb45a773dfd3dcd380af7/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927", size = 148644, upload-time = "2025-08-09T07:56:30.984Z" }, + { url = "https://files.pythonhosted.org/packages/77/d9/cbcf1a2a5c7d7856f11e7ac2d782aec12bdfea60d104e60e0aa1c97849dc/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9", size = 160468, upload-time = "2025-08-09T07:56:32.252Z" }, + { url = "https://files.pythonhosted.org/packages/f6/42/6f45efee8697b89fda4d50580f292b8f7f9306cb2971d4b53f8914e4d890/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5", size = 158187, upload-time = "2025-08-09T07:56:33.481Z" }, + { url = "https://files.pythonhosted.org/packages/70/99/f1c3bdcfaa9c45b3ce96f70b14f070411366fa19549c1d4832c935d8e2c3/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc", size = 152699, upload-time = "2025-08-09T07:56:34.739Z" }, + { url = "https://files.pythonhosted.org/packages/a3/ad/b0081f2f99a4b194bcbb1934ef3b12aa4d9702ced80a37026b7607c72e58/charset_normalizer-3.4.3-cp313-cp313-win32.whl", hash = "sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce", size = 99580, upload-time = "2025-08-09T07:56:35.981Z" }, + { url = "https://files.pythonhosted.org/packages/9a/8f/ae790790c7b64f925e5c953b924aaa42a243fb778fed9e41f147b2a5715a/charset_normalizer-3.4.3-cp313-cp313-win_amd64.whl", hash = "sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef", size = 107366, upload-time = "2025-08-09T07:56:37.339Z" }, + { url = "https://files.pythonhosted.org/packages/8a/1f/f041989e93b001bc4e44bb1669ccdcf54d3f00e628229a85b08d330615c5/charset_normalizer-3.4.3-py3-none-any.whl", hash = "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a", size = 53175, upload-time = "2025-08-09T07:57:26.864Z" }, +] + +[[package]] +name = "choreographer" +version = "1.0.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "logistro" }, + { name = "simplejson" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/71/0e/88c2a0307e27f40bd0ce18e66ba2c8f7327b95b23adc51ea57a08cb96797/choreographer-1.0.10.tar.gz", hash = "sha256:7adf84a0d6a6054386d5cce013fdcadb2426479e49c9b0cb06af7d3712ed263c", size = 40455, upload-time = "2025-08-22T20:37:25.461Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d3/c2/82389f6e20098a414ddcf88d3b8032809b7a66e70f9bc5264f81beb24b4a/choreographer-1.0.10-py3-none-any.whl", hash = "sha256:b23ec2409f38ec89a544558eadeb19688746bab9a0f47e7115477d6e80a14a41", size = 51300, upload-time = "2025-08-22T20:37:24.372Z" }, ] [[package]] @@ -347,8 +380,8 @@ dependencies = [ [[package]] name = "cobra" -version = "0.28.0" -source = { registry = "https://pypi.org/simple" } +version = "0.29.1" +source = { git = "https://github.com/ripaul/cobrapy?rev=hopsy-backend#c1790271e898071a1ebb9fda44e6032fbf982478" } dependencies = [ { name = "appdirs" }, { name = "depinfo" }, @@ -365,72 +398,67 @@ dependencies = [ { name = "ruamel-yaml" }, { name = "swiglpk" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/86/18/91a5759f70e72b2b5d6059171891ef2fc3502a260e558bc892d94d94c686/cobra-0.28.0.tar.gz", hash = "sha256:49cfe0f4b2bb281d7398c43d037f88ea687c788714676c32ccb76c911e3d0367", size = 1164669 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/85/41/9ac0e87ea7c47f50e8e120064300d7fb6f9dd6080aecdd1ffd56181fffc4/cobra-0.28.0-py2.py3-none-any.whl", hash = "sha256:ebacf19a76b613855b27f02924eea9c66c76d7ef975802a23a226ab085fa1deb", size = 1192020 }, -] [[package]] name = "colorama" version = "0.4.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] [[package]] name = "comm" -version = "0.2.2" +version = "0.2.3" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "traitlets" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/e9/a8/fb783cb0abe2b5fded9f55e5703015cdf1c9c85b3669087c538dd15a6a86/comm-0.2.2.tar.gz", hash = "sha256:3fd7a84065306e07bea1773df6eb8282de51ba82f77c72f9c85716ab11fe980e", size = 6210 } +sdist = { url = "https://files.pythonhosted.org/packages/4c/13/7d740c5849255756bc17888787313b61fd38a0a8304fc4f073dfc46122aa/comm-0.2.3.tar.gz", hash = "sha256:2dc8048c10962d55d7ad693be1e7045d891b7ce8d999c97963a5e3e99c055971", size = 6319, upload-time = "2025-07-25T14:02:04.452Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e6/75/49e5bfe642f71f272236b5b2d2691cf915a7283cc0ceda56357b61daa538/comm-0.2.2-py3-none-any.whl", hash = "sha256:e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3", size = 7180 }, + { url = "https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl", hash = "sha256:c615d91d75f7f04f095b30d1c1711babd43bdc6419c1be9886a85f2f4e489417", size = 7294, upload-time = "2025-07-25T14:02:02.896Z" }, ] [[package]] name = "commitizen" -version = "4.1.0" +version = "4.8.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "argcomplete" }, { name = "charset-normalizer" }, { name = "colorama" }, { name = "decli" }, + { name = "importlib-metadata" }, { name = "jinja2" }, { name = "packaging" }, { name = "pyyaml" }, { name = "questionary" }, { name = "termcolor" }, { name = "tomlkit" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7a/c5/66f1b977b48501a33f5fd33253aba14786483b08aba987718d272e99e732/commitizen-4.1.0.tar.gz", hash = "sha256:4f2d9400ec411aec1c738d4c63fc7fd5807cd6ddf6be970869e03e68b88ff718", size = 51252 } +sdist = { url = "https://files.pythonhosted.org/packages/ee/c0/fe5ba5555f2891bcb0b3e7dc1c57fcfd206ab7133a3094d70b81fd5a4a10/commitizen-4.8.3.tar.gz", hash = "sha256:303ebdc271217aadbb6a73a015612121291d180c8cdd05b5251c7923d4a14195", size = 56225, upload-time = "2025-06-09T14:18:51.472Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/48/f7/7f70adfbf3553ffdbe391eaacde72b21dbc1b4226ae56ca32e8ded1bf70b/commitizen-4.1.0-py3-none-any.whl", hash = "sha256:2e6c5fbd442cab4bcc5a04bc86ef2196ef84bcf611317d6c596e87f5bb4c09f5", size = 72282 }, + { url = "https://files.pythonhosted.org/packages/11/37/5a8e1dadd02eede38bf5a92af108071f6a11b6fc50b7ae27d9083c649ba9/commitizen-4.8.3-py3-none-any.whl", hash = "sha256:91f261387ca2bbb4ab6c79a1a6378dc1576ffb40e3b7dbee201724d95aceba38", size = 80112, upload-time = "2025-06-09T14:18:49.673Z" }, ] [[package]] name = "commitlint" -version = "1.3.0" +version = "1.3.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bb/12/61ea68efec07118b2e5a9c0be5a8cb94a77d62dc90609d66eb9d0feebd69/commitlint-1.3.0.tar.gz", hash = "sha256:a8d7f2de60ed0d29d63c1ff2bd71c31acd9425b5e2c2685d90c09abfbb2e3c7f", size = 28914 } +sdist = { url = "https://files.pythonhosted.org/packages/99/c1/42ee438955d0df9bf311dc4c573a49fb7215d915b224ee49566c6d11a318/commitlint-1.3.1.tar.gz", hash = "sha256:2a0123636bd12cb47f96034af0711d302403e80e47bac815f26c495420929d53", size = 23896, upload-time = "2025-08-25T13:19:35.965Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/58/70/d48b07b8b56c5864a716902dd5bcc439f68ca72dc22784824dcb9448507d/commitlint-1.3.0-py3-none-any.whl", hash = "sha256:64691dace7caa58ab9bdf904fca27d899935025b445a1c216c911d8fba0b22e4", size = 27314 }, + { url = "https://files.pythonhosted.org/packages/78/bb/7413a18bff34f38a0b3283558dc25119c21426964619080e0061aadd3bb0/commitlint-1.3.1-py3-none-any.whl", hash = "sha256:02024a64a785c7b5f2c6accb33415efb61d428b90e0231480ac49b8b07624520", size = 26643, upload-time = "2025-08-25T13:19:35.173Z" }, ] [[package]] name = "como" -version = "1.11.1" source = { editable = "." } dependencies = [ { name = "aioftp" }, + { name = "anndata" }, { name = "cobamp" }, { name = "cobra" }, { name = "fast-bioservices" }, + { name = "gurobipy" }, + { name = "hopsy" }, { name = "kaleido" }, { name = "loguru" }, { name = "numpy" }, @@ -455,9 +483,6 @@ dev = [ { name = "pytest-cov" }, { name = "ruff" }, ] -gurobi = [ - { name = "gurobipy" }, -] interactive = [ { name = "ipython" }, { name = "jupyterlab" }, @@ -466,23 +491,28 @@ interactive = [ [package.dev-dependencies] dev = [ { name = "como" }, + { name = "pandas-stubs" }, + { name = "pre-commit" }, + { name = "scipy-stubs" }, ] [package.metadata] requires-dist = [ { name = "aioftp", specifier = ">=0.23.1" }, + { name = "anndata", specifier = ">=0.12.0" }, { name = "cobamp", git = "https://github.com/JoshLoecker/cobamp?rev=master" }, - { name = "cobra", specifier = ">=0.28.0" }, + { name = "cobra", git = "https://github.com/ripaul/cobrapy?rev=hopsy-backend" }, { name = "commitizen", marker = "extra == 'dev'", specifier = ">=4.1.0" }, { name = "commitlint", marker = "extra == 'dev'", specifier = ">=1.3.0" }, { name = "fast-bioservices", specifier = ">=0.3.9" }, - { name = "gurobipy", marker = "extra == 'gurobi'", specifier = ">=10.0.0" }, + { name = "gurobipy", specifier = "<14" }, + { name = "hopsy", specifier = ">=1.6.1" }, { name = "hypothesis", marker = "extra == 'dev'", specifier = ">=6.122.1" }, { name = "ipython", marker = "extra == 'interactive'", specifier = ">=8.0.0" }, { name = "jupyterlab", marker = "extra == 'interactive'", specifier = ">=4.3.2" }, - { name = "kaleido", specifier = "==0.2.1" }, + { name = "kaleido", specifier = ">=0.2.1" }, { name = "loguru", specifier = ">=0.7.2" }, - { name = "numpy", specifier = "<2.0" }, + { name = "numpy", specifier = ">2.0" }, { name = "openpyxl", specifier = ">=3.1.5" }, { name = "pandas", specifier = ">=1.3.5" }, { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.3.3" }, @@ -491,95 +521,134 @@ requires-dist = [ { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.8.0" }, { name = "scanpy", specifier = ">=1.10.4" }, { name = "scikit-learn", specifier = ">=1.5.2" }, - { name = "scipy", specifier = ">=1.7.3" }, + { name = "scipy", specifier = ">=1.13.0" }, { name = "seaborn", specifier = ">=0.13.2" }, - { name = "setuptools", specifier = "<60.0" }, - { name = "statsmodels", specifier = ">=0.13.0" }, + { name = "setuptools", specifier = ">=78.1.1" }, + { name = "statsmodels", marker = "python_full_version < '3.12'", specifier = ">=0.13.0" }, { name = "statsmodels", marker = "python_full_version >= '3.12'", specifier = ">=0.14.0" }, { name = "troppo", git = "https://github.com/JoshLoecker/troppo?rev=master" }, ] +provides-extras = ["dev", "interactive"] [package.metadata.requires-dev] -dev = [{ name = "como", editable = "." }] +dev = [ + { name = "como", editable = "." }, + { name = "pandas-stubs", specifier = ">=2.3.2.250827" }, + { name = "pre-commit", specifier = ">=4.2.0" }, + { name = "scipy-stubs", specifier = ">=1.16.1.1" }, +] [[package]] name = "contourpy" -version = "1.2.1" +version = "1.3.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8d/9e/e4786569b319847ffd98a8326802d5cf8a5500860dbfc2df1f0f4883ed99/contourpy-1.2.1.tar.gz", hash = "sha256:4d8908b3bee1c889e547867ca4cdc54e5ab6be6d3e078556814a22457f49423c", size = 13457196 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/64/2a/e389ad2e209db9f9db59598fabd5f4b515eccabef4df71d07c0b77c1b2d7/contourpy-1.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bd7c23df857d488f418439686d3b10ae2fbf9bc256cd045b37a8c16575ea1040", size = 260792 }, - { url = "https://files.pythonhosted.org/packages/d8/d5/f23beca650c8aab67e72f610d65817c68c306e6f6a124ca337fcec7d5d57/contourpy-1.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5b9eb0ca724a241683c9685a484da9d35c872fd42756574a7cfbf58af26677fd", size = 244848 }, - { url = "https://files.pythonhosted.org/packages/1c/72/66e920088a9bebbc2e356626a1763cabbd4e7199ce29e7f89818dc2757bf/contourpy-1.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c75507d0a55378240f781599c30e7776674dbaf883a46d1c90f37e563453480", size = 300760 }, - { url = "https://files.pythonhosted.org/packages/73/a0/a6533b607e5ffce2e1780e94056da8ec034849136747f42e7232fa1a11e2/contourpy-1.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11959f0ce4a6f7b76ec578576a0b61a28bdc0696194b6347ba3f1c53827178b9", size = 336330 }, - { url = "https://files.pythonhosted.org/packages/87/75/a57c116798f34b16154d61bf1d2c00968f2eed8ae9aebe0760f2e2776da2/contourpy-1.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb3315a8a236ee19b6df481fc5f997436e8ade24a9f03dfdc6bd490fea20c6da", size = 310178 }, - { url = "https://files.pythonhosted.org/packages/67/0f/6e5b4879594cd1cbb6a2754d9230937be444f404cf07c360c07a10b36aac/contourpy-1.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39f3ecaf76cd98e802f094e0d4fbc6dc9c45a8d0c4d185f0f6c2234e14e5f75b", size = 305232 }, - { url = "https://files.pythonhosted.org/packages/d3/c3/05e085167bc4fe8f919d6812700fc7738cd6b07f5ac9e904d5ec5bf2cd7a/contourpy-1.2.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:94b34f32646ca0414237168d68a9157cb3889f06b096612afdd296003fdd32fd", size = 807382 }, - { url = "https://files.pythonhosted.org/packages/21/7f/a5ecf64f0bbb17d9a2b12bf934a2ccbcb35b53a289d41e450927c1eb2690/contourpy-1.2.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:457499c79fa84593f22454bbd27670227874cd2ff5d6c84e60575c8b50a69619", size = 831069 }, - { url = "https://files.pythonhosted.org/packages/8c/5e/f6ee233fa88b73156e7812f823ea7372a8161beb209a0812801383ffe737/contourpy-1.2.1-cp310-cp310-win32.whl", hash = "sha256:ac58bdee53cbeba2ecad824fa8159493f0bf3b8ea4e93feb06c9a465d6c87da8", size = 166724 }, - { url = "https://files.pythonhosted.org/packages/b6/b2/27c7a0d46c7dceb9083272eb314bef1ed43e5280a4197719656f866b496d/contourpy-1.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:9cffe0f850e89d7c0012a1fb8730f75edd4320a0a731ed0c183904fe6ecfc3a9", size = 187455 }, - { url = "https://files.pythonhosted.org/packages/33/0e/51ff72fac17e2500baf30b6b2a24be423a8d27e1625e5de99f585b852d74/contourpy-1.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6022cecf8f44e36af10bd9118ca71f371078b4c168b6e0fab43d4a889985dbb5", size = 262121 }, - { url = "https://files.pythonhosted.org/packages/9f/6b/8a1ca4b81d426c104fe42b3cfad9488eaaef0a03fcf98eaecc22b628a013/contourpy-1.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ef5adb9a3b1d0c645ff694f9bca7702ec2c70f4d734f9922ea34de02294fdf72", size = 245940 }, - { url = "https://files.pythonhosted.org/packages/98/72/ae1e8518a2fe75980598a2716e392c7642b70b6a5605fc925426007b0f49/contourpy-1.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6150ffa5c767bc6332df27157d95442c379b7dce3a38dff89c0f39b63275696f", size = 302068 }, - { url = "https://files.pythonhosted.org/packages/64/a0/59c5d9c5c2c687d255dfa0c2826008a544c0ba53b718ba253e7cd46cf2ad/contourpy-1.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c863140fafc615c14a4bf4efd0f4425c02230eb8ef02784c9a156461e62c965", size = 336482 }, - { url = "https://files.pythonhosted.org/packages/38/78/912e4457d6dbb182780ad1ed26c875a3bc3f9aa678e42f766f7cc6683919/contourpy-1.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:00e5388f71c1a0610e6fe56b5c44ab7ba14165cdd6d695429c5cd94021e390b2", size = 311520 }, - { url = "https://files.pythonhosted.org/packages/ee/c0/9bd123d676eb61750e116a2cd915b06483fc406143cfc36c7f263f0f5368/contourpy-1.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4492d82b3bc7fbb7e3610747b159869468079fe149ec5c4d771fa1f614a14df", size = 306008 }, - { url = "https://files.pythonhosted.org/packages/a6/fc/ba17428cda0d5226015c7c844fb0909cb38945dc9d6770634acfc3b96d6b/contourpy-1.2.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:49e70d111fee47284d9dd867c9bb9a7058a3c617274900780c43e38d90fe1205", size = 808551 }, - { url = "https://files.pythonhosted.org/packages/d1/0a/dc0c74a760665bd0548fc515cf2a83eb9235d72cfe88fd84f3a6fefc6052/contourpy-1.2.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b59c0ffceff8d4d3996a45f2bb6f4c207f94684a96bf3d9728dbb77428dd8cb8", size = 831450 }, - { url = "https://files.pythonhosted.org/packages/f2/b0/88c7e96f5ecc6ae564c5043b25f789ebbd8d173ecb47d1080edbdb2f335e/contourpy-1.2.1-cp311-cp311-win32.whl", hash = "sha256:7b4182299f251060996af5249c286bae9361fa8c6a9cda5efc29fe8bfd6062ec", size = 167278 }, - { url = "https://files.pythonhosted.org/packages/d6/4f/76d0dd0bca417691918484c26c74dd9dd44fbf528bbfeb30d754886e2c54/contourpy-1.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2855c8b0b55958265e8b5888d6a615ba02883b225f2227461aa9127c578a4922", size = 188181 }, - { url = "https://files.pythonhosted.org/packages/6b/4c/62e2595cd71cfd802dd0436b6c29f6d9ced1ad9fb32899e770ff7aa9c81e/contourpy-1.2.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:62828cada4a2b850dbef89c81f5a33741898b305db244904de418cc957ff05dc", size = 263283 }, - { url = "https://files.pythonhosted.org/packages/51/03/36ecc6fd1d018336625ad91b91fd34cd9ba8da5d36f5e1167dfe3275070a/contourpy-1.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:309be79c0a354afff9ff7da4aaed7c3257e77edf6c1b448a779329431ee79d7e", size = 245311 }, - { url = "https://files.pythonhosted.org/packages/64/d8/6c6446db0a4f9e026656869a46b6d3740dddd4965e1933666b65f6efba3b/contourpy-1.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e785e0f2ef0d567099b9ff92cbfb958d71c2d5b9259981cd9bee81bd194c9a4", size = 285670 }, - { url = "https://files.pythonhosted.org/packages/ab/f7/dbef23f63777ca50517c5aa130c38abcb8b3f353e0adb41942ac9dd34995/contourpy-1.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cac0a8f71a041aa587410424ad46dfa6a11f6149ceb219ce7dd48f6b02b87a7", size = 333947 }, - { url = "https://files.pythonhosted.org/packages/23/d3/a34f938dec3461af5bb42e76e330ae4547951036204b2cba948fe30b4bf7/contourpy-1.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af3f4485884750dddd9c25cb7e3915d83c2db92488b38ccb77dd594eac84c4a0", size = 308709 }, - { url = "https://files.pythonhosted.org/packages/01/29/65d81d2546a2487d57e16b2b789bbc0279b081766a75587e60002f16a6b8/contourpy-1.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ce6889abac9a42afd07a562c2d6d4b2b7134f83f18571d859b25624a331c90b", size = 309182 }, - { url = "https://files.pythonhosted.org/packages/85/f6/1aba852441f5961b8944413b1b9e6797bd32f173f4cee35873a8e2145c73/contourpy-1.2.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a1eea9aecf761c661d096d39ed9026574de8adb2ae1c5bd7b33558af884fb2ce", size = 806353 }, - { url = "https://files.pythonhosted.org/packages/0a/b2/e51c4d13e79c5150d99e62ca1fc0a08bc550096663f077e04d7e832b42b7/contourpy-1.2.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:187fa1d4c6acc06adb0fae5544c59898ad781409e61a926ac7e84b8f276dcef4", size = 829368 }, - { url = "https://files.pythonhosted.org/packages/01/f8/65fafbc5374920cf6c842f415bb60de4c36c1c194eb45ca6b488ae012cef/contourpy-1.2.1-cp312-cp312-win32.whl", hash = "sha256:c2528d60e398c7c4c799d56f907664673a807635b857df18f7ae64d3e6ce2d9f", size = 167497 }, - { url = "https://files.pythonhosted.org/packages/78/38/a046bb0ebce6f530175d434e7364149e338ffe1069ee286ed8ba7f6481ee/contourpy-1.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:1a07fc092a4088ee952ddae19a2b2a85757b923217b7eed584fdf25f53a6e7ce", size = 189901 }, +sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174, upload-time = "2025-07-26T12:03:12.549Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/2e/c4390a31919d8a78b90e8ecf87cd4b4c4f05a5b48d05ec17db8e5404c6f4/contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1", size = 288773, upload-time = "2025-07-26T12:01:02.277Z" }, + { url = "https://files.pythonhosted.org/packages/0d/44/c4b0b6095fef4dc9c420e041799591e3b63e9619e3044f7f4f6c21c0ab24/contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381", size = 270149, upload-time = "2025-07-26T12:01:04.072Z" }, + { url = "https://files.pythonhosted.org/packages/30/2e/dd4ced42fefac8470661d7cb7e264808425e6c5d56d175291e93890cce09/contourpy-1.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:929ddf8c4c7f348e4c0a5a3a714b5c8542ffaa8c22954862a46ca1813b667ee7", size = 329222, upload-time = "2025-07-26T12:01:05.688Z" }, + { url = "https://files.pythonhosted.org/packages/f2/74/cc6ec2548e3d276c71389ea4802a774b7aa3558223b7bade3f25787fafc2/contourpy-1.3.3-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9e999574eddae35f1312c2b4b717b7885d4edd6cb46700e04f7f02db454e67c1", size = 377234, upload-time = "2025-07-26T12:01:07.054Z" }, + { url = "https://files.pythonhosted.org/packages/03/b3/64ef723029f917410f75c09da54254c5f9ea90ef89b143ccadb09df14c15/contourpy-1.3.3-cp311-cp311-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf67e0e3f482cb69779dd3061b534eb35ac9b17f163d851e2a547d56dba0a3a", size = 380555, upload-time = "2025-07-26T12:01:08.801Z" }, + { url = "https://files.pythonhosted.org/packages/5f/4b/6157f24ca425b89fe2eb7e7be642375711ab671135be21e6faa100f7448c/contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db", size = 355238, upload-time = "2025-07-26T12:01:10.319Z" }, + { url = "https://files.pythonhosted.org/packages/98/56/f914f0dd678480708a04cfd2206e7c382533249bc5001eb9f58aa693e200/contourpy-1.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:598c3aaece21c503615fd59c92a3598b428b2f01bfb4b8ca9c4edeecc2438620", size = 1326218, upload-time = "2025-07-26T12:01:12.659Z" }, + { url = "https://files.pythonhosted.org/packages/fb/d7/4a972334a0c971acd5172389671113ae82aa7527073980c38d5868ff1161/contourpy-1.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:322ab1c99b008dad206d406bb61d014cf0174df491ae9d9d0fac6a6fda4f977f", size = 1392867, upload-time = "2025-07-26T12:01:15.533Z" }, + { url = "https://files.pythonhosted.org/packages/75/3e/f2cc6cd56dc8cff46b1a56232eabc6feea52720083ea71ab15523daab796/contourpy-1.3.3-cp311-cp311-win32.whl", hash = "sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff", size = 183677, upload-time = "2025-07-26T12:01:17.088Z" }, + { url = "https://files.pythonhosted.org/packages/98/4b/9bd370b004b5c9d8045c6c33cf65bae018b27aca550a3f657cdc99acdbd8/contourpy-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42", size = 225234, upload-time = "2025-07-26T12:01:18.256Z" }, + { url = "https://files.pythonhosted.org/packages/d9/b6/71771e02c2e004450c12b1120a5f488cad2e4d5b590b1af8bad060360fe4/contourpy-1.3.3-cp311-cp311-win_arm64.whl", hash = "sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470", size = 193123, upload-time = "2025-07-26T12:01:19.848Z" }, + { url = "https://files.pythonhosted.org/packages/be/45/adfee365d9ea3d853550b2e735f9d66366701c65db7855cd07621732ccfc/contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb", size = 293419, upload-time = "2025-07-26T12:01:21.16Z" }, + { url = "https://files.pythonhosted.org/packages/53/3e/405b59cfa13021a56bba395a6b3aca8cec012b45bf177b0eaf7a202cde2c/contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6", size = 273979, upload-time = "2025-07-26T12:01:22.448Z" }, + { url = "https://files.pythonhosted.org/packages/d4/1c/a12359b9b2ca3a845e8f7f9ac08bdf776114eb931392fcad91743e2ea17b/contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7", size = 332653, upload-time = "2025-07-26T12:01:24.155Z" }, + { url = "https://files.pythonhosted.org/packages/63/12/897aeebfb475b7748ea67b61e045accdfcf0d971f8a588b67108ed7f5512/contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8", size = 379536, upload-time = "2025-07-26T12:01:25.91Z" }, + { url = "https://files.pythonhosted.org/packages/43/8a/a8c584b82deb248930ce069e71576fc09bd7174bbd35183b7943fb1064fd/contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea", size = 384397, upload-time = "2025-07-26T12:01:27.152Z" }, + { url = "https://files.pythonhosted.org/packages/cc/8f/ec6289987824b29529d0dfda0d74a07cec60e54b9c92f3c9da4c0ac732de/contourpy-1.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1", size = 362601, upload-time = "2025-07-26T12:01:28.808Z" }, + { url = "https://files.pythonhosted.org/packages/05/0a/a3fe3be3ee2dceb3e615ebb4df97ae6f3828aa915d3e10549ce016302bd1/contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7", size = 1331288, upload-time = "2025-07-26T12:01:31.198Z" }, + { url = "https://files.pythonhosted.org/packages/33/1d/acad9bd4e97f13f3e2b18a3977fe1b4a37ecf3d38d815333980c6c72e963/contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411", size = 1403386, upload-time = "2025-07-26T12:01:33.947Z" }, + { url = "https://files.pythonhosted.org/packages/cf/8f/5847f44a7fddf859704217a99a23a4f6417b10e5ab1256a179264561540e/contourpy-1.3.3-cp312-cp312-win32.whl", hash = "sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69", size = 185018, upload-time = "2025-07-26T12:01:35.64Z" }, + { url = "https://files.pythonhosted.org/packages/19/e8/6026ed58a64563186a9ee3f29f41261fd1828f527dd93d33b60feca63352/contourpy-1.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b", size = 226567, upload-time = "2025-07-26T12:01:36.804Z" }, + { url = "https://files.pythonhosted.org/packages/d1/e2/f05240d2c39a1ed228d8328a78b6f44cd695f7ef47beb3e684cf93604f86/contourpy-1.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc", size = 193655, upload-time = "2025-07-26T12:01:37.999Z" }, + { url = "https://files.pythonhosted.org/packages/68/35/0167aad910bbdb9599272bd96d01a9ec6852f36b9455cf2ca67bd4cc2d23/contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5", size = 293257, upload-time = "2025-07-26T12:01:39.367Z" }, + { url = "https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1", size = 274034, upload-time = "2025-07-26T12:01:40.645Z" }, + { url = "https://files.pythonhosted.org/packages/73/23/90e31ceeed1de63058a02cb04b12f2de4b40e3bef5e082a7c18d9c8ae281/contourpy-1.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286", size = 334672, upload-time = "2025-07-26T12:01:41.942Z" }, + { url = "https://files.pythonhosted.org/packages/ed/93/b43d8acbe67392e659e1d984700e79eb67e2acb2bd7f62012b583a7f1b55/contourpy-1.3.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5", size = 381234, upload-time = "2025-07-26T12:01:43.499Z" }, + { url = "https://files.pythonhosted.org/packages/46/3b/bec82a3ea06f66711520f75a40c8fc0b113b2a75edb36aa633eb11c4f50f/contourpy-1.3.3-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67", size = 385169, upload-time = "2025-07-26T12:01:45.219Z" }, + { url = "https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9", size = 362859, upload-time = "2025-07-26T12:01:46.519Z" }, + { url = "https://files.pythonhosted.org/packages/33/71/e2a7945b7de4e58af42d708a219f3b2f4cff7386e6b6ab0a0fa0033c49a9/contourpy-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659", size = 1332062, upload-time = "2025-07-26T12:01:48.964Z" }, + { url = "https://files.pythonhosted.org/packages/12/fc/4e87ac754220ccc0e807284f88e943d6d43b43843614f0a8afa469801db0/contourpy-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7", size = 1403932, upload-time = "2025-07-26T12:01:51.979Z" }, + { url = "https://files.pythonhosted.org/packages/a6/2e/adc197a37443f934594112222ac1aa7dc9a98faf9c3842884df9a9d8751d/contourpy-1.3.3-cp313-cp313-win32.whl", hash = "sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d", size = 185024, upload-time = "2025-07-26T12:01:53.245Z" }, + { url = "https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263", size = 226578, upload-time = "2025-07-26T12:01:54.422Z" }, + { url = "https://files.pythonhosted.org/packages/8a/9a/2f6024a0c5995243cd63afdeb3651c984f0d2bc727fd98066d40e141ad73/contourpy-1.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9", size = 193524, upload-time = "2025-07-26T12:01:55.73Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b3/f8a1a86bd3298513f500e5b1f5fd92b69896449f6cab6a146a5d52715479/contourpy-1.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d", size = 306730, upload-time = "2025-07-26T12:01:57.051Z" }, + { url = "https://files.pythonhosted.org/packages/3f/11/4780db94ae62fc0c2053909b65dc3246bd7cecfc4f8a20d957ad43aa4ad8/contourpy-1.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216", size = 287897, upload-time = "2025-07-26T12:01:58.663Z" }, + { url = "https://files.pythonhosted.org/packages/ae/15/e59f5f3ffdd6f3d4daa3e47114c53daabcb18574a26c21f03dc9e4e42ff0/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae", size = 326751, upload-time = "2025-07-26T12:02:00.343Z" }, + { url = "https://files.pythonhosted.org/packages/0f/81/03b45cfad088e4770b1dcf72ea78d3802d04200009fb364d18a493857210/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20", size = 375486, upload-time = "2025-07-26T12:02:02.128Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ba/49923366492ffbdd4486e970d421b289a670ae8cf539c1ea9a09822b371a/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99", size = 388106, upload-time = "2025-07-26T12:02:03.615Z" }, + { url = "https://files.pythonhosted.org/packages/9f/52/5b00ea89525f8f143651f9f03a0df371d3cbd2fccd21ca9b768c7a6500c2/contourpy-1.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b", size = 352548, upload-time = "2025-07-26T12:02:05.165Z" }, + { url = "https://files.pythonhosted.org/packages/32/1d/a209ec1a3a3452d490f6b14dd92e72280c99ae3d1e73da74f8277d4ee08f/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a", size = 1322297, upload-time = "2025-07-26T12:02:07.379Z" }, + { url = "https://files.pythonhosted.org/packages/bc/9e/46f0e8ebdd884ca0e8877e46a3f4e633f6c9c8c4f3f6e72be3fe075994aa/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e", size = 1391023, upload-time = "2025-07-26T12:02:10.171Z" }, + { url = "https://files.pythonhosted.org/packages/b9/70/f308384a3ae9cd2209e0849f33c913f658d3326900d0ff5d378d6a1422d2/contourpy-1.3.3-cp313-cp313t-win32.whl", hash = "sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3", size = 196157, upload-time = "2025-07-26T12:02:11.488Z" }, + { url = "https://files.pythonhosted.org/packages/b2/dd/880f890a6663b84d9e34a6f88cded89d78f0091e0045a284427cb6b18521/contourpy-1.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8", size = 240570, upload-time = "2025-07-26T12:02:12.754Z" }, + { url = "https://files.pythonhosted.org/packages/80/99/2adc7d8ffead633234817ef8e9a87115c8a11927a94478f6bb3d3f4d4f7d/contourpy-1.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301", size = 199713, upload-time = "2025-07-26T12:02:14.4Z" }, + { url = "https://files.pythonhosted.org/packages/a5/29/8dcfe16f0107943fa92388c23f6e05cff0ba58058c4c95b00280d4c75a14/contourpy-1.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497", size = 278809, upload-time = "2025-07-26T12:02:52.74Z" }, + { url = "https://files.pythonhosted.org/packages/85/a9/8b37ef4f7dafeb335daee3c8254645ef5725be4d9c6aa70b50ec46ef2f7e/contourpy-1.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8", size = 261593, upload-time = "2025-07-26T12:02:54.037Z" }, + { url = "https://files.pythonhosted.org/packages/0a/59/ebfb8c677c75605cc27f7122c90313fd2f375ff3c8d19a1694bda74aaa63/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e", size = 302202, upload-time = "2025-07-26T12:02:55.947Z" }, + { url = "https://files.pythonhosted.org/packages/3c/37/21972a15834d90bfbfb009b9d004779bd5a07a0ec0234e5ba8f64d5736f4/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ed3657edf08512fc3fe81b510e35c2012fbd3081d2e26160f27ca28affec989", size = 329207, upload-time = "2025-07-26T12:02:57.468Z" }, + { url = "https://files.pythonhosted.org/packages/0c/58/bd257695f39d05594ca4ad60df5bcb7e32247f9951fd09a9b8edb82d1daa/contourpy-1.3.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77", size = 225315, upload-time = "2025-07-26T12:02:58.801Z" }, ] [[package]] name = "coverage" -version = "7.6.8" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ab/75/aecfd0a3adbec6e45753976bc2a9fed62b42cea9a206d10fd29244a77953/coverage-7.6.8.tar.gz", hash = "sha256:8b2b8503edb06822c86d82fa64a4a5cb0760bb8f31f26e138ec743f422f37cfc", size = 801425 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/31/86/6ed22e101badc8eedf181f0c2f65500df5929c44c79991cf45b9bf741424/coverage-7.6.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b39e6011cd06822eb964d038d5dff5da5d98652b81f5ecd439277b32361a3a50", size = 206988 }, - { url = "https://files.pythonhosted.org/packages/3b/04/16853c58bacc02b3ff5405193dfc6c66632442d931b23dd7b9452dc55cf3/coverage-7.6.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:63c19702db10ad79151a059d2d6336fe0c470f2e18d0d4d1a57f7f9713875dcf", size = 207418 }, - { url = "https://files.pythonhosted.org/packages/f8/eb/8a91520d04215eb549d6a7d7d3a79cbb1d78b5dd0814f4b23bf97521d580/coverage-7.6.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3985b9be361d8fb6b2d1adc9924d01dec575a1d7453a14cccd73225cb79243ee", size = 235860 }, - { url = "https://files.pythonhosted.org/packages/00/10/bf1ede5b54ae1bbf39921a5dd4cc84aee79041ed301ec8955064785ddb90/coverage-7.6.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:644ec81edec0f4ad17d51c838a7d01e42811054543b76d4ba2c5d6af741ce2a6", size = 233766 }, - { url = "https://files.pythonhosted.org/packages/5c/ea/741d9233eb502906e0d18ccf4c15c4fb74ff0e85fd8ee967590194b889a1/coverage-7.6.8-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f188a2402f8359cf0c4b1fe89eea40dc13b52e7b4fd4812450da9fcd210181d", size = 234924 }, - { url = "https://files.pythonhosted.org/packages/18/43/b2cfd4413a5b64ab27c289228b0c45b4527d1b99381cc9d6a00bfd515da4/coverage-7.6.8-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e19122296822deafce89a0c5e8685704c067ae65d45e79718c92df7b3ec3d331", size = 234019 }, - { url = "https://files.pythonhosted.org/packages/8e/95/8b2fbb9d1a79277963b6095cd51a90fb7088cd3618faf75550038331f78b/coverage-7.6.8-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:13618bed0c38acc418896005732e565b317aa9e98d855a0e9f211a7ffc2d6638", size = 232481 }, - { url = "https://files.pythonhosted.org/packages/4d/d7/9e939508a39ef67605b715ca89c6522214aceb27c2db9152ae3ae1cf8626/coverage-7.6.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:193e3bffca48ad74b8c764fb4492dd875038a2f9925530cb094db92bb5e47bed", size = 233609 }, - { url = "https://files.pythonhosted.org/packages/ba/e2/1c5fb52eafcffeebaa9db084bff47e7c3cf4f97db752226c232cee4d530b/coverage-7.6.8-cp310-cp310-win32.whl", hash = "sha256:3988665ee376abce49613701336544041f2117de7b7fbfe91b93d8ff8b151c8e", size = 209669 }, - { url = "https://files.pythonhosted.org/packages/31/31/6a56469609a252549dd4b090815428d5521edd4642440d987573a450c069/coverage-7.6.8-cp310-cp310-win_amd64.whl", hash = "sha256:f56f49b2553d7dd85fd86e029515a221e5c1f8cb3d9c38b470bc38bde7b8445a", size = 210509 }, - { url = "https://files.pythonhosted.org/packages/ab/9f/e98211980f6e2f439e251737482aa77906c9b9c507824c71a2ce7eea0402/coverage-7.6.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:86cffe9c6dfcfe22e28027069725c7f57f4b868a3f86e81d1c62462764dc46d4", size = 207093 }, - { url = "https://files.pythonhosted.org/packages/fd/c7/8bab83fb9c20f7f8163c5a20dcb62d591b906a214a6dc6b07413074afc80/coverage-7.6.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d82ab6816c3277dc962cfcdc85b1efa0e5f50fb2c449432deaf2398a2928ab94", size = 207536 }, - { url = "https://files.pythonhosted.org/packages/1e/d6/00243df625f1b282bb25c83ce153ae2c06f8e7a796a8d833e7235337b4d9/coverage-7.6.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13690e923a3932e4fad4c0ebfb9cb5988e03d9dcb4c5150b5fcbf58fd8bddfc4", size = 239482 }, - { url = "https://files.pythonhosted.org/packages/1e/07/faf04b3eeb55ffc2a6f24b65dffe6e0359ec3b283e6efb5050ea0707446f/coverage-7.6.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4be32da0c3827ac9132bb488d331cb32e8d9638dd41a0557c5569d57cf22c9c1", size = 236886 }, - { url = "https://files.pythonhosted.org/packages/43/23/c79e497bf4d8fcacd316bebe1d559c765485b8ec23ac4e23025be6bfce09/coverage-7.6.8-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44e6c85bbdc809383b509d732b06419fb4544dca29ebe18480379633623baafb", size = 238749 }, - { url = "https://files.pythonhosted.org/packages/b5/e5/791bae13be3c6451e32ef7af1192e711c6a319f3c597e9b218d148fd0633/coverage-7.6.8-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:768939f7c4353c0fac2f7c37897e10b1414b571fd85dd9fc49e6a87e37a2e0d8", size = 237679 }, - { url = "https://files.pythonhosted.org/packages/05/c6/bbfdfb03aada601fb8993ced17468c8c8e0b4aafb3097026e680fabb7ce1/coverage-7.6.8-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e44961e36cb13c495806d4cac67640ac2866cb99044e210895b506c26ee63d3a", size = 236317 }, - { url = "https://files.pythonhosted.org/packages/67/f9/f8e5a4b2ce96d1b0e83ae6246369eb8437001dc80ec03bb51c87ff557cd8/coverage-7.6.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3ea8bb1ab9558374c0ab591783808511d135a833c3ca64a18ec927f20c4030f0", size = 237084 }, - { url = "https://files.pythonhosted.org/packages/f0/70/b05328901e4debe76e033717e1452d00246c458c44e9dbd893e7619c2967/coverage-7.6.8-cp311-cp311-win32.whl", hash = "sha256:629a1ba2115dce8bf75a5cce9f2486ae483cb89c0145795603d6554bdc83e801", size = 209638 }, - { url = "https://files.pythonhosted.org/packages/70/55/1efa24f960a2fa9fbc44a9523d3f3c50ceb94dd1e8cd732168ab2dc41b07/coverage-7.6.8-cp311-cp311-win_amd64.whl", hash = "sha256:fb9fc32399dca861584d96eccd6c980b69bbcd7c228d06fb74fe53e007aa8ef9", size = 210506 }, - { url = "https://files.pythonhosted.org/packages/76/ce/3edf581c8fe429ed8ced6e6d9ac693c25975ef9093413276dab6ed68a80a/coverage-7.6.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e683e6ecc587643f8cde8f5da6768e9d165cd31edf39ee90ed7034f9ca0eefee", size = 207285 }, - { url = "https://files.pythonhosted.org/packages/09/9c/cf102ab046c9cf8895c3f7aadcde6f489a4b2ec326757e8c6e6581829b5e/coverage-7.6.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1defe91d41ce1bd44b40fabf071e6a01a5aa14de4a31b986aa9dfd1b3e3e414a", size = 207522 }, - { url = "https://files.pythonhosted.org/packages/39/06/42aa6dd13dbfca72e1fd8ffccadbc921b6e75db34545ebab4d955d1e7ad3/coverage-7.6.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7ad66e8e50225ebf4236368cc43c37f59d5e6728f15f6e258c8639fa0dd8e6d", size = 240543 }, - { url = "https://files.pythonhosted.org/packages/a0/20/2932971dc215adeca8eeff446266a7fef17a0c238e881ffedebe7bfa0669/coverage-7.6.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3fe47da3e4fda5f1abb5709c156eca207eacf8007304ce3019eb001e7a7204cb", size = 237577 }, - { url = "https://files.pythonhosted.org/packages/ac/85/4323ece0cd5452c9522f4b6e5cc461e6c7149a4b1887c9e7a8b1f4e51146/coverage-7.6.8-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:202a2d645c5a46b84992f55b0a3affe4f0ba6b4c611abec32ee88358db4bb649", size = 239646 }, - { url = "https://files.pythonhosted.org/packages/77/52/b2537487d8f36241e518e84db6f79e26bc3343b14844366e35b090fae0d4/coverage-7.6.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4674f0daa1823c295845b6a740d98a840d7a1c11df00d1fd62614545c1583787", size = 239128 }, - { url = "https://files.pythonhosted.org/packages/7c/99/7f007762012186547d0ecc3d328da6b6f31a8c99f05dc1e13dcd929918cd/coverage-7.6.8-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:74610105ebd6f33d7c10f8907afed696e79c59e3043c5f20eaa3a46fddf33b4c", size = 237434 }, - { url = "https://files.pythonhosted.org/packages/97/53/e9b5cf0682a1cab9352adfac73caae0d77ae1d65abc88975d510f7816389/coverage-7.6.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37cda8712145917105e07aab96388ae76e787270ec04bcb9d5cc786d7cbb8443", size = 239095 }, - { url = "https://files.pythonhosted.org/packages/0c/50/054f0b464fbae0483217186478eefa2e7df3a79917ed7f1d430b6da2cf0d/coverage-7.6.8-cp312-cp312-win32.whl", hash = "sha256:9e89d5c8509fbd6c03d0dd1972925b22f50db0792ce06324ba069f10787429ad", size = 209895 }, - { url = "https://files.pythonhosted.org/packages/df/d0/09ba870360a27ecf09e177ca2ff59d4337fc7197b456f22ceff85cffcfa5/coverage-7.6.8-cp312-cp312-win_amd64.whl", hash = "sha256:379c111d3558272a2cae3d8e57e6b6e6f4fe652905692d54bad5ea0ca37c5ad4", size = 210684 }, - { url = "https://files.pythonhosted.org/packages/32/df/0d2476121cd0bfb9ca2413efe02289c474b82c4b134863bef4b89ec7bcfa/coverage-7.6.8-pp39.pp310-none-any.whl", hash = "sha256:5c52a036535d12590c32c49209e79cabaad9f9ad8aa4cbd875b68c4d67a9cbce", size = 199230 }, +version = "7.10.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/14/70/025b179c993f019105b79575ac6edb5e084fb0f0e63f15cdebef4e454fb5/coverage-7.10.6.tar.gz", hash = "sha256:f644a3ae5933a552a29dbb9aa2f90c677a875f80ebea028e5a52a4f429044b90", size = 823736, upload-time = "2025-08-29T15:35:16.668Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d4/16/2bea27e212c4980753d6d563a0803c150edeaaddb0771a50d2afc410a261/coverage-7.10.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c706db3cabb7ceef779de68270150665e710b46d56372455cd741184f3868d8f", size = 217129, upload-time = "2025-08-29T15:33:13.575Z" }, + { url = "https://files.pythonhosted.org/packages/2a/51/e7159e068831ab37e31aac0969d47b8c5ee25b7d307b51e310ec34869315/coverage-7.10.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e0c38dc289e0508ef68ec95834cb5d2e96fdbe792eaccaa1bccac3966bbadcc", size = 217532, upload-time = "2025-08-29T15:33:14.872Z" }, + { url = "https://files.pythonhosted.org/packages/e7/c0/246ccbea53d6099325d25cd208df94ea435cd55f0db38099dd721efc7a1f/coverage-7.10.6-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:752a3005a1ded28f2f3a6e8787e24f28d6abe176ca64677bcd8d53d6fe2ec08a", size = 247931, upload-time = "2025-08-29T15:33:16.142Z" }, + { url = "https://files.pythonhosted.org/packages/7d/fb/7435ef8ab9b2594a6e3f58505cc30e98ae8b33265d844007737946c59389/coverage-7.10.6-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:689920ecfd60f992cafca4f5477d55720466ad2c7fa29bb56ac8d44a1ac2b47a", size = 249864, upload-time = "2025-08-29T15:33:17.434Z" }, + { url = "https://files.pythonhosted.org/packages/51/f8/d9d64e8da7bcddb094d511154824038833c81e3a039020a9d6539bf303e9/coverage-7.10.6-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ec98435796d2624d6905820a42f82149ee9fc4f2d45c2c5bc5a44481cc50db62", size = 251969, upload-time = "2025-08-29T15:33:18.822Z" }, + { url = "https://files.pythonhosted.org/packages/43/28/c43ba0ef19f446d6463c751315140d8f2a521e04c3e79e5c5fe211bfa430/coverage-7.10.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b37201ce4a458c7a758ecc4efa92fa8ed783c66e0fa3c42ae19fc454a0792153", size = 249659, upload-time = "2025-08-29T15:33:20.407Z" }, + { url = "https://files.pythonhosted.org/packages/79/3e/53635bd0b72beaacf265784508a0b386defc9ab7fad99ff95f79ce9db555/coverage-7.10.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:2904271c80898663c810a6b067920a61dd8d38341244a3605bd31ab55250dad5", size = 247714, upload-time = "2025-08-29T15:33:21.751Z" }, + { url = "https://files.pythonhosted.org/packages/4c/55/0964aa87126624e8c159e32b0bc4e84edef78c89a1a4b924d28dd8265625/coverage-7.10.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5aea98383463d6e1fa4e95416d8de66f2d0cb588774ee20ae1b28df826bcb619", size = 248351, upload-time = "2025-08-29T15:33:23.105Z" }, + { url = "https://files.pythonhosted.org/packages/eb/ab/6cfa9dc518c6c8e14a691c54e53a9433ba67336c760607e299bfcf520cb1/coverage-7.10.6-cp311-cp311-win32.whl", hash = "sha256:e3fb1fa01d3598002777dd259c0c2e6d9d5e10e7222976fc8e03992f972a2cba", size = 219562, upload-time = "2025-08-29T15:33:24.717Z" }, + { url = "https://files.pythonhosted.org/packages/5b/18/99b25346690cbc55922e7cfef06d755d4abee803ef335baff0014268eff4/coverage-7.10.6-cp311-cp311-win_amd64.whl", hash = "sha256:f35ed9d945bece26553d5b4c8630453169672bea0050a564456eb88bdffd927e", size = 220453, upload-time = "2025-08-29T15:33:26.482Z" }, + { url = "https://files.pythonhosted.org/packages/d8/ed/81d86648a07ccb124a5cf1f1a7788712b8d7216b593562683cd5c9b0d2c1/coverage-7.10.6-cp311-cp311-win_arm64.whl", hash = "sha256:99e1a305c7765631d74b98bf7dbf54eeea931f975e80f115437d23848ee8c27c", size = 219127, upload-time = "2025-08-29T15:33:27.777Z" }, + { url = "https://files.pythonhosted.org/packages/26/06/263f3305c97ad78aab066d116b52250dd316e74fcc20c197b61e07eb391a/coverage-7.10.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5b2dd6059938063a2c9fee1af729d4f2af28fd1a545e9b7652861f0d752ebcea", size = 217324, upload-time = "2025-08-29T15:33:29.06Z" }, + { url = "https://files.pythonhosted.org/packages/e9/60/1e1ded9a4fe80d843d7d53b3e395c1db3ff32d6c301e501f393b2e6c1c1f/coverage-7.10.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:388d80e56191bf846c485c14ae2bc8898aa3124d9d35903fef7d907780477634", size = 217560, upload-time = "2025-08-29T15:33:30.748Z" }, + { url = "https://files.pythonhosted.org/packages/b8/25/52136173c14e26dfed8b106ed725811bb53c30b896d04d28d74cb64318b3/coverage-7.10.6-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:90cb5b1a4670662719591aa92d0095bb41714970c0b065b02a2610172dbf0af6", size = 249053, upload-time = "2025-08-29T15:33:32.041Z" }, + { url = "https://files.pythonhosted.org/packages/cb/1d/ae25a7dc58fcce8b172d42ffe5313fc267afe61c97fa872b80ee72d9515a/coverage-7.10.6-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:961834e2f2b863a0e14260a9a273aff07ff7818ab6e66d2addf5628590c628f9", size = 251802, upload-time = "2025-08-29T15:33:33.625Z" }, + { url = "https://files.pythonhosted.org/packages/f5/7a/1f561d47743710fe996957ed7c124b421320f150f1d38523d8d9102d3e2a/coverage-7.10.6-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf9a19f5012dab774628491659646335b1928cfc931bf8d97b0d5918dd58033c", size = 252935, upload-time = "2025-08-29T15:33:34.909Z" }, + { url = "https://files.pythonhosted.org/packages/6c/ad/8b97cd5d28aecdfde792dcbf646bac141167a5cacae2cd775998b45fabb5/coverage-7.10.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:99c4283e2a0e147b9c9cc6bc9c96124de9419d6044837e9799763a0e29a7321a", size = 250855, upload-time = "2025-08-29T15:33:36.922Z" }, + { url = "https://files.pythonhosted.org/packages/33/6a/95c32b558d9a61858ff9d79580d3877df3eb5bc9eed0941b1f187c89e143/coverage-7.10.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:282b1b20f45df57cc508c1e033403f02283adfb67d4c9c35a90281d81e5c52c5", size = 248974, upload-time = "2025-08-29T15:33:38.175Z" }, + { url = "https://files.pythonhosted.org/packages/0d/9c/8ce95dee640a38e760d5b747c10913e7a06554704d60b41e73fdea6a1ffd/coverage-7.10.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8cdbe264f11afd69841bd8c0d83ca10b5b32853263ee62e6ac6a0ab63895f972", size = 250409, upload-time = "2025-08-29T15:33:39.447Z" }, + { url = "https://files.pythonhosted.org/packages/04/12/7a55b0bdde78a98e2eb2356771fd2dcddb96579e8342bb52aa5bc52e96f0/coverage-7.10.6-cp312-cp312-win32.whl", hash = "sha256:a517feaf3a0a3eca1ee985d8373135cfdedfbba3882a5eab4362bda7c7cf518d", size = 219724, upload-time = "2025-08-29T15:33:41.172Z" }, + { url = "https://files.pythonhosted.org/packages/36/4a/32b185b8b8e327802c9efce3d3108d2fe2d9d31f153a0f7ecfd59c773705/coverage-7.10.6-cp312-cp312-win_amd64.whl", hash = "sha256:856986eadf41f52b214176d894a7de05331117f6035a28ac0016c0f63d887629", size = 220536, upload-time = "2025-08-29T15:33:42.524Z" }, + { url = "https://files.pythonhosted.org/packages/08/3a/d5d8dc703e4998038c3099eaf77adddb00536a3cec08c8dcd556a36a3eb4/coverage-7.10.6-cp312-cp312-win_arm64.whl", hash = "sha256:acf36b8268785aad739443fa2780c16260ee3fa09d12b3a70f772ef100939d80", size = 219171, upload-time = "2025-08-29T15:33:43.974Z" }, + { url = "https://files.pythonhosted.org/packages/bd/e7/917e5953ea29a28c1057729c1d5af9084ab6d9c66217523fd0e10f14d8f6/coverage-7.10.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ffea0575345e9ee0144dfe5701aa17f3ba546f8c3bb48db62ae101afb740e7d6", size = 217351, upload-time = "2025-08-29T15:33:45.438Z" }, + { url = "https://files.pythonhosted.org/packages/eb/86/2e161b93a4f11d0ea93f9bebb6a53f113d5d6e416d7561ca41bb0a29996b/coverage-7.10.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:95d91d7317cde40a1c249d6b7382750b7e6d86fad9d8eaf4fa3f8f44cf171e80", size = 217600, upload-time = "2025-08-29T15:33:47.269Z" }, + { url = "https://files.pythonhosted.org/packages/0e/66/d03348fdd8df262b3a7fb4ee5727e6e4936e39e2f3a842e803196946f200/coverage-7.10.6-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3e23dd5408fe71a356b41baa82892772a4cefcf758f2ca3383d2aa39e1b7a003", size = 248600, upload-time = "2025-08-29T15:33:48.953Z" }, + { url = "https://files.pythonhosted.org/packages/73/dd/508420fb47d09d904d962f123221bc249f64b5e56aa93d5f5f7603be475f/coverage-7.10.6-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0f3f56e4cb573755e96a16501a98bf211f100463d70275759e73f3cbc00d4f27", size = 251206, upload-time = "2025-08-29T15:33:50.697Z" }, + { url = "https://files.pythonhosted.org/packages/e9/1f/9020135734184f439da85c70ea78194c2730e56c2d18aee6e8ff1719d50d/coverage-7.10.6-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:db4a1d897bbbe7339946ffa2fe60c10cc81c43fab8b062d3fcb84188688174a4", size = 252478, upload-time = "2025-08-29T15:33:52.303Z" }, + { url = "https://files.pythonhosted.org/packages/a4/a4/3d228f3942bb5a2051fde28c136eea23a761177dc4ff4ef54533164ce255/coverage-7.10.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d8fd7879082953c156d5b13c74aa6cca37f6a6f4747b39538504c3f9c63d043d", size = 250637, upload-time = "2025-08-29T15:33:53.67Z" }, + { url = "https://files.pythonhosted.org/packages/36/e3/293dce8cdb9a83de971637afc59b7190faad60603b40e32635cbd15fbf61/coverage-7.10.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:28395ca3f71cd103b8c116333fa9db867f3a3e1ad6a084aa3725ae002b6583bc", size = 248529, upload-time = "2025-08-29T15:33:55.022Z" }, + { url = "https://files.pythonhosted.org/packages/90/26/64eecfa214e80dd1d101e420cab2901827de0e49631d666543d0e53cf597/coverage-7.10.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:61c950fc33d29c91b9e18540e1aed7d9f6787cc870a3e4032493bbbe641d12fc", size = 250143, upload-time = "2025-08-29T15:33:56.386Z" }, + { url = "https://files.pythonhosted.org/packages/3e/70/bd80588338f65ea5b0d97e424b820fb4068b9cfb9597fbd91963086e004b/coverage-7.10.6-cp313-cp313-win32.whl", hash = "sha256:160c00a5e6b6bdf4e5984b0ef21fc860bc94416c41b7df4d63f536d17c38902e", size = 219770, upload-time = "2025-08-29T15:33:58.063Z" }, + { url = "https://files.pythonhosted.org/packages/a7/14/0b831122305abcc1060c008f6c97bbdc0a913ab47d65070a01dc50293c2b/coverage-7.10.6-cp313-cp313-win_amd64.whl", hash = "sha256:628055297f3e2aa181464c3808402887643405573eb3d9de060d81531fa79d32", size = 220566, upload-time = "2025-08-29T15:33:59.766Z" }, + { url = "https://files.pythonhosted.org/packages/83/c6/81a83778c1f83f1a4a168ed6673eeedc205afb562d8500175292ca64b94e/coverage-7.10.6-cp313-cp313-win_arm64.whl", hash = "sha256:df4ec1f8540b0bcbe26ca7dd0f541847cc8a108b35596f9f91f59f0c060bfdd2", size = 219195, upload-time = "2025-08-29T15:34:01.191Z" }, + { url = "https://files.pythonhosted.org/packages/d7/1c/ccccf4bf116f9517275fa85047495515add43e41dfe8e0bef6e333c6b344/coverage-7.10.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:c9a8b7a34a4de3ed987f636f71881cd3b8339f61118b1aa311fbda12741bff0b", size = 218059, upload-time = "2025-08-29T15:34:02.91Z" }, + { url = "https://files.pythonhosted.org/packages/92/97/8a3ceff833d27c7492af4f39d5da6761e9ff624831db9e9f25b3886ddbca/coverage-7.10.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8dd5af36092430c2b075cee966719898f2ae87b636cefb85a653f1d0ba5d5393", size = 218287, upload-time = "2025-08-29T15:34:05.106Z" }, + { url = "https://files.pythonhosted.org/packages/92/d8/50b4a32580cf41ff0423777a2791aaf3269ab60c840b62009aec12d3970d/coverage-7.10.6-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b0353b0f0850d49ada66fdd7d0c7cdb0f86b900bb9e367024fd14a60cecc1e27", size = 259625, upload-time = "2025-08-29T15:34:06.575Z" }, + { url = "https://files.pythonhosted.org/packages/7e/7e/6a7df5a6fb440a0179d94a348eb6616ed4745e7df26bf2a02bc4db72c421/coverage-7.10.6-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d6b9ae13d5d3e8aeca9ca94198aa7b3ebbc5acfada557d724f2a1f03d2c0b0df", size = 261801, upload-time = "2025-08-29T15:34:08.006Z" }, + { url = "https://files.pythonhosted.org/packages/3a/4c/a270a414f4ed5d196b9d3d67922968e768cd971d1b251e1b4f75e9362f75/coverage-7.10.6-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:675824a363cc05781b1527b39dc2587b8984965834a748177ee3c37b64ffeafb", size = 264027, upload-time = "2025-08-29T15:34:09.806Z" }, + { url = "https://files.pythonhosted.org/packages/9c/8b/3210d663d594926c12f373c5370bf1e7c5c3a427519a8afa65b561b9a55c/coverage-7.10.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:692d70ea725f471a547c305f0d0fc6a73480c62fb0da726370c088ab21aed282", size = 261576, upload-time = "2025-08-29T15:34:11.585Z" }, + { url = "https://files.pythonhosted.org/packages/72/d0/e1961eff67e9e1dba3fc5eb7a4caf726b35a5b03776892da8d79ec895775/coverage-7.10.6-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:851430a9a361c7a8484a36126d1d0ff8d529d97385eacc8dfdc9bfc8c2d2cbe4", size = 259341, upload-time = "2025-08-29T15:34:13.159Z" }, + { url = "https://files.pythonhosted.org/packages/3a/06/d6478d152cd189b33eac691cba27a40704990ba95de49771285f34a5861e/coverage-7.10.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d9369a23186d189b2fc95cc08b8160ba242057e887d766864f7adf3c46b2df21", size = 260468, upload-time = "2025-08-29T15:34:14.571Z" }, + { url = "https://files.pythonhosted.org/packages/ed/73/737440247c914a332f0b47f7598535b29965bf305e19bbc22d4c39615d2b/coverage-7.10.6-cp313-cp313t-win32.whl", hash = "sha256:92be86fcb125e9bda0da7806afd29a3fd33fdf58fba5d60318399adf40bf37d0", size = 220429, upload-time = "2025-08-29T15:34:16.394Z" }, + { url = "https://files.pythonhosted.org/packages/bd/76/b92d3214740f2357ef4a27c75a526eb6c28f79c402e9f20a922c295c05e2/coverage-7.10.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6b3039e2ca459a70c79523d39347d83b73f2f06af5624905eba7ec34d64d80b5", size = 221493, upload-time = "2025-08-29T15:34:17.835Z" }, + { url = "https://files.pythonhosted.org/packages/fc/8e/6dcb29c599c8a1f654ec6cb68d76644fe635513af16e932d2d4ad1e5ac6e/coverage-7.10.6-cp313-cp313t-win_arm64.whl", hash = "sha256:3fb99d0786fe17b228eab663d16bee2288e8724d26a199c29325aac4b0319b9b", size = 219757, upload-time = "2025-08-29T15:34:19.248Z" }, + { url = "https://files.pythonhosted.org/packages/44/0c/50db5379b615854b5cf89146f8f5bd1d5a9693d7f3a987e269693521c404/coverage-7.10.6-py3-none-any.whl", hash = "sha256:92c4ecf6bf11b2e85fd4d8204814dc26e6a19f0c9d938c207c5cb0eadfcabbe3", size = 208986, upload-time = "2025-08-29T15:35:14.506Z" }, ] [package.optional-dependencies] @@ -587,115 +656,179 @@ toml = [ { name = "tomli", marker = "python_full_version <= '3.11'" }, ] +[[package]] +name = "crc32c" +version = "2.7.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7f/4c/4e40cc26347ac8254d3f25b9f94710b8e8df24ee4dddc1ba41907a88a94d/crc32c-2.7.1.tar.gz", hash = "sha256:f91b144a21eef834d64178e01982bb9179c354b3e9e5f4c803b0e5096384968c", size = 45712, upload-time = "2024-09-24T06:20:17.553Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/45/8e/2f37f46368bbfd50edfc11b96f0aa135699034b1b020966c70ebaff3463b/crc32c-2.7.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:19e03a50545a3ef400bd41667d5525f71030488629c57d819e2dd45064f16192", size = 49672, upload-time = "2024-09-24T06:18:18.032Z" }, + { url = "https://files.pythonhosted.org/packages/ed/b8/e52f7c4b045b871c2984d70f37c31d4861b533a8082912dfd107a96cf7c1/crc32c-2.7.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8c03286b1e5ce9bed7090084f206aacd87c5146b4b10de56fe9e86cbbbf851cf", size = 37155, upload-time = "2024-09-24T06:18:19.373Z" }, + { url = "https://files.pythonhosted.org/packages/25/ee/0cfa82a68736697f3c7e435ba658c2ef8c997f42b89f6ab4545efe1b2649/crc32c-2.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:80ebbf144a1a56a532b353e81fa0f3edca4f4baa1bf92b1dde2c663a32bb6a15", size = 35372, upload-time = "2024-09-24T06:18:20.983Z" }, + { url = "https://files.pythonhosted.org/packages/aa/92/c878aaba81c431fcd93a059e9f6c90db397c585742793f0bf6e0c531cc67/crc32c-2.7.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96b794fd11945298fdd5eb1290a812efb497c14bc42592c5c992ca077458eeba", size = 54879, upload-time = "2024-09-24T06:18:23.085Z" }, + { url = "https://files.pythonhosted.org/packages/5b/f5/ab828ab3907095e06b18918408748950a9f726ee2b37be1b0839fb925ee1/crc32c-2.7.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9df7194dd3c0efb5a21f5d70595b7a8b4fd9921fbbd597d6d8e7a11eca3e2d27", size = 52588, upload-time = "2024-09-24T06:18:24.463Z" }, + { url = "https://files.pythonhosted.org/packages/6a/2b/9e29e9ac4c4213d60491db09487125db358cd9263490fbadbd55e48fbe03/crc32c-2.7.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d698eec444b18e296a104d0b9bb6c596c38bdcb79d24eba49604636e9d747305", size = 53674, upload-time = "2024-09-24T06:18:25.624Z" }, + { url = "https://files.pythonhosted.org/packages/79/ed/df3c4c14bf1b29f5c9b52d51fb6793e39efcffd80b2941d994e8f7f5f688/crc32c-2.7.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e07cf10ef852d219d179333fd706d1c415626f1f05e60bd75acf0143a4d8b225", size = 54691, upload-time = "2024-09-24T06:18:26.578Z" }, + { url = "https://files.pythonhosted.org/packages/0c/47/4917af3c9c1df2fff28bbfa6492673c9adeae5599dcc207bbe209847489c/crc32c-2.7.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d2a051f296e6e92e13efee3b41db388931cdb4a2800656cd1ed1d9fe4f13a086", size = 52896, upload-time = "2024-09-24T06:18:28.174Z" }, + { url = "https://files.pythonhosted.org/packages/1b/6f/26fc3dda5835cda8f6cd9d856afe62bdeae428de4c34fea200b0888e8835/crc32c-2.7.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a1738259802978cdf428f74156175da6a5fdfb7256f647fdc0c9de1bc6cd7173", size = 53554, upload-time = "2024-09-24T06:18:29.104Z" }, + { url = "https://files.pythonhosted.org/packages/56/3e/6f39127f7027c75d130c0ba348d86a6150dff23761fbc6a5f71659f4521e/crc32c-2.7.1-cp311-cp311-win32.whl", hash = "sha256:f7786d219a1a1bf27d0aa1869821d11a6f8e90415cfffc1e37791690d4a848a1", size = 38370, upload-time = "2024-09-24T06:18:30.013Z" }, + { url = "https://files.pythonhosted.org/packages/c9/fb/1587c2705a3a47a3d0067eecf9a6fec510761c96dec45c7b038fb5c8ff46/crc32c-2.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:887f6844bb3ad35f0778cd10793ad217f7123a5422e40041231b8c4c7329649d", size = 39795, upload-time = "2024-09-24T06:18:31.324Z" }, + { url = "https://files.pythonhosted.org/packages/1d/02/998dc21333413ce63fe4c1ca70eafe61ca26afc7eb353f20cecdb77d614e/crc32c-2.7.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f7d1c4e761fe42bf856130daf8b2658df33fe0ced3c43dadafdfeaa42b57b950", size = 49568, upload-time = "2024-09-24T06:18:32.425Z" }, + { url = "https://files.pythonhosted.org/packages/9c/3e/e3656bfa76e50ef87b7136fef2dbf3c46e225629432fc9184fdd7fd187ff/crc32c-2.7.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:73361c79a6e4605204457f19fda18b042a94508a52e53d10a4239da5fb0f6a34", size = 37019, upload-time = "2024-09-24T06:18:34.097Z" }, + { url = "https://files.pythonhosted.org/packages/0b/7d/5ff9904046ad15a08772515db19df43107bf5e3901a89c36a577b5f40ba0/crc32c-2.7.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:afd778fc8ac0ed2ffbfb122a9aa6a0e409a8019b894a1799cda12c01534493e0", size = 35373, upload-time = "2024-09-24T06:18:35.02Z" }, + { url = "https://files.pythonhosted.org/packages/4d/41/4aedc961893f26858ab89fc772d0eaba91f9870f19eaa933999dcacb94ec/crc32c-2.7.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56ef661b34e9f25991fface7f9ad85e81bbc1b3fe3b916fd58c893eabe2fa0b8", size = 54675, upload-time = "2024-09-24T06:18:35.954Z" }, + { url = "https://files.pythonhosted.org/packages/d6/63/8cabf09b7e39b9fec8f7010646c8b33057fc8d67e6093b3cc15563d23533/crc32c-2.7.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:571aa4429444b5d7f588e4377663592145d2d25eb1635abb530f1281794fc7c9", size = 52386, upload-time = "2024-09-24T06:18:36.896Z" }, + { url = "https://files.pythonhosted.org/packages/79/13/13576941bf7cf95026abae43d8427c812c0054408212bf8ed490eda846b0/crc32c-2.7.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c02a3bd67dea95cdb25844aaf44ca2e1b0c1fd70b287ad08c874a95ef4bb38db", size = 53495, upload-time = "2024-09-24T06:18:38.099Z" }, + { url = "https://files.pythonhosted.org/packages/3d/b6/55ffb26d0517d2d6c6f430ce2ad36ae7647c995c5bfd7abce7f32bb2bad1/crc32c-2.7.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:99d17637c4867672cb8adeea007294e3c3df9d43964369516cfe2c1f47ce500a", size = 54456, upload-time = "2024-09-24T06:18:39.051Z" }, + { url = "https://files.pythonhosted.org/packages/c2/1a/5562e54cb629ecc5543d3604dba86ddfc7c7b7bf31d64005b38a00d31d31/crc32c-2.7.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f4a400ac3c69a32e180d8753fd7ec7bccb80ade7ab0812855dce8a208e72495f", size = 52647, upload-time = "2024-09-24T06:18:40.021Z" }, + { url = "https://files.pythonhosted.org/packages/48/ec/ce4138eaf356cd9aae60bbe931755e5e0151b3eca5f491fce6c01b97fd59/crc32c-2.7.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:588587772e55624dd9c7a906ec9e8773ae0b6ac5e270fc0bc84ee2758eba90d5", size = 53332, upload-time = "2024-09-24T06:18:40.925Z" }, + { url = "https://files.pythonhosted.org/packages/5e/b5/144b42cd838a901175a916078781cb2c3c9f977151c9ba085aebd6d15b22/crc32c-2.7.1-cp312-cp312-win32.whl", hash = "sha256:9f14b60e5a14206e8173dd617fa0c4df35e098a305594082f930dae5488da428", size = 38371, upload-time = "2024-09-24T06:18:42.711Z" }, + { url = "https://files.pythonhosted.org/packages/ae/c4/7929dcd5d9b57db0cce4fe6f6c191049380fc6d8c9b9f5581967f4ec018e/crc32c-2.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:7c810a246660a24dc818047dc5f89c7ce7b2814e1e08a8e99993f4103f7219e8", size = 39805, upload-time = "2024-09-24T06:18:43.6Z" }, + { url = "https://files.pythonhosted.org/packages/bf/98/1a6d60d5b3b5edc8382777b64100343cb4aa6a7e172fae4a6cfcb8ebbbd9/crc32c-2.7.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:24949bffb06fc411cc18188d33357923cb935273642164d0bb37a5f375654169", size = 49567, upload-time = "2024-09-24T06:18:44.485Z" }, + { url = "https://files.pythonhosted.org/packages/4f/56/0dd652d4e950e6348bbf16b964b3325e4ad8220470774128fc0b0dd069cb/crc32c-2.7.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2d5d326e7e118d4fa60187770d86b66af2fdfc63ce9eeb265f0d3e7d49bebe0b", size = 37018, upload-time = "2024-09-24T06:18:45.434Z" }, + { url = "https://files.pythonhosted.org/packages/47/02/2bd65fdef10139b6a802d83a7f966b7750fe5ffb1042f7cbe5dbb6403869/crc32c-2.7.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ba110df60c64c8e2d77a9425b982a520ccdb7abe42f06604f4d98a45bb1fff62", size = 35374, upload-time = "2024-09-24T06:18:46.304Z" }, + { url = "https://files.pythonhosted.org/packages/a9/0d/3e797d1ed92d357a6a4c5b41cea15a538b27a8fdf18c7863747eb50b73ad/crc32c-2.7.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c277f9d16a3283e064d54854af0976b72abaa89824955579b2b3f37444f89aae", size = 54641, upload-time = "2024-09-24T06:18:47.207Z" }, + { url = "https://files.pythonhosted.org/packages/a7/d3/4ddeef755caaa75680c559562b6c71f5910fee4c4f3a2eb5ea8b57f0e48c/crc32c-2.7.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:881af0478a01331244e27197356929edbdeaef6a9f81b5c6bacfea18d2139289", size = 52338, upload-time = "2024-09-24T06:18:49.31Z" }, + { url = "https://files.pythonhosted.org/packages/01/cf/32f019be5de9f6e180926a50ee5f08648e686c7d9a59f2c5d0806a77b1c7/crc32c-2.7.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:724d5ff4d29ff093a983ae656be3307093706d850ea2a233bf29fcacc335d945", size = 53447, upload-time = "2024-09-24T06:18:50.296Z" }, + { url = "https://files.pythonhosted.org/packages/b2/8b/92f3f62f3bafe8f7ab4af7bfb7246dc683fd11ec0d6dfb73f91e09079f69/crc32c-2.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b2416c4d88696ac322632555c0f81ab35e15f154bc96055da6cf110d642dbc10", size = 54484, upload-time = "2024-09-24T06:18:51.311Z" }, + { url = "https://files.pythonhosted.org/packages/98/b2/113a50f8781f76af5ac65ffdb907e72bddbe974de8e02247f0d58bc48040/crc32c-2.7.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:60254251b88ec9b9795215f0f9ec015a6b5eef8b2c5fba1267c672d83c78fc02", size = 52703, upload-time = "2024-09-24T06:18:52.488Z" }, + { url = "https://files.pythonhosted.org/packages/b4/6c/309229e9acda8cf36a8ff4061d70b54d905f79b7037e16883ce6590a24ab/crc32c-2.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:edefc0e46f3c37372183f70338e5bdee42f6789b62fcd36ec53aa933e9dfbeaf", size = 53367, upload-time = "2024-09-24T06:18:53.49Z" }, + { url = "https://files.pythonhosted.org/packages/b5/2a/6c6324d920396e1bd9f3efbe8753da071be0ca52bd22d6c82d446b8d6975/crc32c-2.7.1-cp313-cp313-win32.whl", hash = "sha256:813af8111218970fe2adb833c5e5239f091b9c9e76f03b4dd91aaba86e99b499", size = 38377, upload-time = "2024-09-24T06:18:54.487Z" }, + { url = "https://files.pythonhosted.org/packages/db/a0/f01ccfab538db07ef3f6b4ede46357ff147a81dd4f3c59ca6a34c791a549/crc32c-2.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:7d9ede7be8e4ec1c9e90aaf6884decbeef10e3473e6ddac032706d710cab5888", size = 39803, upload-time = "2024-09-24T06:18:55.419Z" }, + { url = "https://files.pythonhosted.org/packages/1b/80/61dcae7568b33acfde70c9d651c7d891c0c578c39cc049107c1cf61f1367/crc32c-2.7.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:db9ac92294284b22521356715784b91cc9094eee42a5282ab281b872510d1831", size = 49386, upload-time = "2024-09-24T06:18:56.813Z" }, + { url = "https://files.pythonhosted.org/packages/1e/f1/80f17c089799ab2b4c247443bdd101d6ceda30c46d7f193e16b5ca29c5a0/crc32c-2.7.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8fcd7f2f29a30dc92af64a9ee3d38bde0c82bd20ad939999427aac94bbd87373", size = 36937, upload-time = "2024-09-24T06:18:57.77Z" }, + { url = "https://files.pythonhosted.org/packages/63/42/5fcfc71a3de493d920fd2590843762a2749981ea56b802b380e5df82309d/crc32c-2.7.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5c056ef043393085523e149276a7ce0cb534b872e04f3e20d74d9a94a75c0ad7", size = 35292, upload-time = "2024-09-24T06:18:58.676Z" }, + { url = "https://files.pythonhosted.org/packages/03/de/fef962e898a953558fe1c55141644553e84ef4190693a31244c59a0856c7/crc32c-2.7.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03a92551a343702629af91f78d205801219692b6909f8fa126b830e332bfb0e0", size = 54223, upload-time = "2024-09-24T06:18:59.675Z" }, + { url = "https://files.pythonhosted.org/packages/21/14/fceca1a6f45c0a1814fe8602a65657b75c27425162445925ba87438cad6b/crc32c-2.7.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb9424ec1a8ca54763155a703e763bcede82e6569fe94762614bb2de1412d4e1", size = 51588, upload-time = "2024-09-24T06:19:00.938Z" }, + { url = "https://files.pythonhosted.org/packages/13/3b/13d40a7dfbf9ef05c84a0da45544ee72080dca4ce090679e5105689984bd/crc32c-2.7.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88732070f6175530db04e0bb36880ac45c33d49f8ac43fa0e50cfb1830049d23", size = 52678, upload-time = "2024-09-24T06:19:02.661Z" }, + { url = "https://files.pythonhosted.org/packages/36/09/65ffc4fb9fa60ff6714eeb50a92284a4525e5943f0b040b572c0c76368c1/crc32c-2.7.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:57a20dfc27995f568f64775eea2bbb58ae269f1a1144561df5e4a4955f79db32", size = 53847, upload-time = "2024-09-24T06:19:03.705Z" }, + { url = "https://files.pythonhosted.org/packages/24/71/938e926085b7288da052db7c84416f3ce25e71baf7ab5b63824c7bcb6f22/crc32c-2.7.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:f7186d098bfd2cff25eac6880b7c7ad80431b90610036131c1c7dd0eab42a332", size = 51860, upload-time = "2024-09-24T06:19:04.726Z" }, + { url = "https://files.pythonhosted.org/packages/3c/d8/4526d5380189d6f2fa27256c204100f30214fe402f47cf6e9fb9a91ab890/crc32c-2.7.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:55a77e29a265418fa34bef15bd0f2c60afae5348988aaf35ed163b4bbf93cf37", size = 52508, upload-time = "2024-09-24T06:19:05.731Z" }, + { url = "https://files.pythonhosted.org/packages/19/30/15f7e35176488b77e5b88751947d321d603fccac273099ace27c7b2d50a6/crc32c-2.7.1-cp313-cp313t-win32.whl", hash = "sha256:ae38a4b6aa361595d81cab441405fbee905c72273e80a1c010fb878ae77ac769", size = 38319, upload-time = "2024-09-24T06:19:07.233Z" }, + { url = "https://files.pythonhosted.org/packages/19/c4/0b3eee04dac195f4730d102d7a9fbea894ae7a32ce075f84336df96a385d/crc32c-2.7.1-cp313-cp313t-win_amd64.whl", hash = "sha256:eee2a43b663feb6c79a6c1c6e5eae339c2b72cfac31ee54ec0209fa736cf7ee5", size = 39781, upload-time = "2024-09-24T06:19:08.182Z" }, +] + [[package]] name = "cycler" version = "0.12.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615 } +sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615, upload-time = "2023-10-07T05:32:18.335Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321 }, + { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321, upload-time = "2023-10-07T05:32:16.783Z" }, ] [[package]] name = "debugpy" -version = "1.8.9" +version = "1.8.16" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/88/92/15b454c516c4c53cc8c03967e4be12b65a1ea36db3bb4513a7453f75c8d8/debugpy-1.8.9.zip", hash = "sha256:1339e14c7d980407248f09824d1b25ff5c5616651689f1e0f0e51bdead3ea13e", size = 4921695 } +sdist = { url = "https://files.pythonhosted.org/packages/ca/d4/722d0bcc7986172ac2ef3c979ad56a1030e3afd44ced136d45f8142b1f4a/debugpy-1.8.16.tar.gz", hash = "sha256:31e69a1feb1cf6b51efbed3f6c9b0ef03bc46ff050679c4be7ea6d2e23540870", size = 1643809, upload-time = "2025-08-06T18:00:02.647Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d0/2e/92fda96b1b773e454daae3e2962726dd9f7aedb1f26d7f2ca353d91a930b/debugpy-1.8.9-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:cfe1e6c6ad7178265f74981edf1154ffce97b69005212fbc90ca22ddfe3d017e", size = 2080529 }, - { url = "https://files.pythonhosted.org/packages/87/c0/d13cdbae394c7ae65ef93d7ccde2ff364445248e367bda93fc0650c08849/debugpy-1.8.9-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ada7fb65102a4d2c9ab62e8908e9e9f12aed9d76ef44880367bc9308ebe49a0f", size = 3565151 }, - { url = "https://files.pythonhosted.org/packages/23/40/237c0a7a68cb982dcced4a0199b7c464630f75b9280d6bebde32490135d1/debugpy-1.8.9-cp310-cp310-win32.whl", hash = "sha256:c36856343cbaa448171cba62a721531e10e7ffb0abff838004701454149bc037", size = 5117068 }, - { url = "https://files.pythonhosted.org/packages/00/89/e0be9f01ee461e3369dde418492244acb1b67adaf04cb5ea98f1380ab101/debugpy-1.8.9-cp310-cp310-win_amd64.whl", hash = "sha256:17c5e0297678442511cf00a745c9709e928ea4ca263d764e90d233208889a19e", size = 5149364 }, - { url = "https://files.pythonhosted.org/packages/f7/bf/c41b688ad490d644b3bcca505a87ea58ec0442234def9a641ba62dce9c11/debugpy-1.8.9-cp311-cp311-macosx_14_0_universal2.whl", hash = "sha256:b74a49753e21e33e7cf030883a92fa607bddc4ede1aa4145172debc637780040", size = 2179080 }, - { url = "https://files.pythonhosted.org/packages/f4/dd/e9de11423db7bde62469fbd932243c64f66d6d87924976f49ec336415522/debugpy-1.8.9-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62d22dacdb0e296966d7d74a7141aaab4bec123fa43d1a35ddcb39bf9fd29d70", size = 3137893 }, - { url = "https://files.pythonhosted.org/packages/2c/bf/e1f2c81220591728f35585b4abd67e71e9b39b3cb983f428b23d4ca6c22e/debugpy-1.8.9-cp311-cp311-win32.whl", hash = "sha256:8138efff315cd09b8dcd14226a21afda4ca582284bf4215126d87342bba1cc66", size = 5042644 }, - { url = "https://files.pythonhosted.org/packages/96/20/a407252954fd2812771e4ea3ab523f73889fd5027e305dec5ee4f0af149a/debugpy-1.8.9-cp311-cp311-win_amd64.whl", hash = "sha256:ff54ef77ad9f5c425398efb150239f6fe8e20c53ae2f68367eba7ece1e96226d", size = 5066943 }, - { url = "https://files.pythonhosted.org/packages/da/ab/1420baf8404d2b499349a44de5037133e06d489009032ce016fedb66eea1/debugpy-1.8.9-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:957363d9a7a6612a37458d9a15e72d03a635047f946e5fceee74b50d52a9c8e2", size = 2504180 }, - { url = "https://files.pythonhosted.org/packages/58/ec/e0f88c6764314bda7887274e0b980812709b3d6363dcae124a49a9ceaa3c/debugpy-1.8.9-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e565fc54b680292b418bb809f1386f17081d1346dca9a871bf69a8ac4071afe", size = 4224563 }, - { url = "https://files.pythonhosted.org/packages/dd/49/d9ea004ee2e4531d2b528841689ee2ba01c6a4b58840efd15e57dd866a86/debugpy-1.8.9-cp312-cp312-win32.whl", hash = "sha256:3e59842d6c4569c65ceb3751075ff8d7e6a6ada209ceca6308c9bde932bcef11", size = 5163641 }, - { url = "https://files.pythonhosted.org/packages/b1/63/c8b0718024c1187a446316037680e1564bf063c6665c815f17b42c244aba/debugpy-1.8.9-cp312-cp312-win_amd64.whl", hash = "sha256:66eeae42f3137eb428ea3a86d4a55f28da9bd5a4a3d369ba95ecc3a92c1bba53", size = 5203862 }, - { url = "https://files.pythonhosted.org/packages/2d/23/3f5804202da11c950dc0caae4a62d0c9aadabdb2daeb5f7aa09838647b5d/debugpy-1.8.9-py2.py3-none-any.whl", hash = "sha256:cc37a6c9987ad743d9c3a14fa1b1a14b7e4e6041f9dd0c8abf8895fe7a97b899", size = 5166094 }, + { url = "https://files.pythonhosted.org/packages/63/d6/ad70ba8b49b23fa286fb21081cf732232cc19374af362051da9c7537ae52/debugpy-1.8.16-cp311-cp311-macosx_14_0_universal2.whl", hash = "sha256:67371b28b79a6a12bcc027d94a06158f2fde223e35b5c4e0783b6f9d3b39274a", size = 2184063, upload-time = "2025-08-06T18:00:11.885Z" }, + { url = "https://files.pythonhosted.org/packages/aa/49/7b03e88dea9759a4c7910143f87f92beb494daaae25560184ff4ae883f9e/debugpy-1.8.16-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2abae6dd02523bec2dee16bd6b0781cccb53fd4995e5c71cc659b5f45581898", size = 3134837, upload-time = "2025-08-06T18:00:13.782Z" }, + { url = "https://files.pythonhosted.org/packages/5d/52/b348930316921de7565fbe37a487d15409041713004f3d74d03eb077dbd4/debugpy-1.8.16-cp311-cp311-win32.whl", hash = "sha256:f8340a3ac2ed4f5da59e064aa92e39edd52729a88fbde7bbaa54e08249a04493", size = 5159142, upload-time = "2025-08-06T18:00:15.391Z" }, + { url = "https://files.pythonhosted.org/packages/d8/ef/9aa9549ce1e10cea696d980292e71672a91ee4a6a691ce5f8629e8f48c49/debugpy-1.8.16-cp311-cp311-win_amd64.whl", hash = "sha256:70f5fcd6d4d0c150a878d2aa37391c52de788c3dc680b97bdb5e529cb80df87a", size = 5183117, upload-time = "2025-08-06T18:00:17.251Z" }, + { url = "https://files.pythonhosted.org/packages/61/fb/0387c0e108d842c902801bc65ccc53e5b91d8c169702a9bbf4f7efcedf0c/debugpy-1.8.16-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:b202e2843e32e80b3b584bcebfe0e65e0392920dc70df11b2bfe1afcb7a085e4", size = 2511822, upload-time = "2025-08-06T18:00:18.526Z" }, + { url = "https://files.pythonhosted.org/packages/37/44/19e02745cae22bf96440141f94e15a69a1afaa3a64ddfc38004668fcdebf/debugpy-1.8.16-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64473c4a306ba11a99fe0bb14622ba4fbd943eb004847d9b69b107bde45aa9ea", size = 4230135, upload-time = "2025-08-06T18:00:19.997Z" }, + { url = "https://files.pythonhosted.org/packages/f3/0b/19b1ba5ee4412f303475a2c7ad5858efb99c90eae5ec627aa6275c439957/debugpy-1.8.16-cp312-cp312-win32.whl", hash = "sha256:833a61ed446426e38b0dd8be3e9d45ae285d424f5bf6cd5b2b559c8f12305508", size = 5281271, upload-time = "2025-08-06T18:00:21.281Z" }, + { url = "https://files.pythonhosted.org/packages/b1/e0/bc62e2dc141de53bd03e2c7cb9d7011de2e65e8bdcdaa26703e4d28656ba/debugpy-1.8.16-cp312-cp312-win_amd64.whl", hash = "sha256:75f204684581e9ef3dc2f67687c3c8c183fde2d6675ab131d94084baf8084121", size = 5323149, upload-time = "2025-08-06T18:00:23.033Z" }, + { url = "https://files.pythonhosted.org/packages/62/66/607ab45cc79e60624df386e233ab64a6d8d39ea02e7f80e19c1d451345bb/debugpy-1.8.16-cp313-cp313-macosx_14_0_universal2.whl", hash = "sha256:85df3adb1de5258dca910ae0bb185e48c98801ec15018a263a92bb06be1c8787", size = 2496157, upload-time = "2025-08-06T18:00:24.361Z" }, + { url = "https://files.pythonhosted.org/packages/4d/a0/c95baae08a75bceabb79868d663a0736655e427ab9c81fb848da29edaeac/debugpy-1.8.16-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bee89e948bc236a5c43c4214ac62d28b29388453f5fd328d739035e205365f0b", size = 4222491, upload-time = "2025-08-06T18:00:25.806Z" }, + { url = "https://files.pythonhosted.org/packages/5b/2f/1c8db6ddd8a257c3cd2c46413b267f1d5fa3df910401c899513ce30392d6/debugpy-1.8.16-cp313-cp313-win32.whl", hash = "sha256:cf358066650439847ec5ff3dae1da98b5461ea5da0173d93d5e10f477c94609a", size = 5281126, upload-time = "2025-08-06T18:00:27.207Z" }, + { url = "https://files.pythonhosted.org/packages/d3/ba/c3e154ab307366d6c5a9c1b68de04914e2ce7fa2f50d578311d8cc5074b2/debugpy-1.8.16-cp313-cp313-win_amd64.whl", hash = "sha256:b5aea1083f6f50023e8509399d7dc6535a351cc9f2e8827d1e093175e4d9fa4c", size = 5323094, upload-time = "2025-08-06T18:00:29.03Z" }, + { url = "https://files.pythonhosted.org/packages/52/57/ecc9ae29fa5b2d90107cd1d9bf8ed19aacb74b2264d986ae9d44fe9bdf87/debugpy-1.8.16-py2.py3-none-any.whl", hash = "sha256:19c9521962475b87da6f673514f7fd610328757ec993bf7ec0d8c96f9a325f9e", size = 5287700, upload-time = "2025-08-06T18:00:42.333Z" }, ] [[package]] name = "decli" -version = "0.6.2" +version = "0.6.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3d/a0/a4658f93ecb589f479037b164dc13c68d108b50bf6594e54c820749f97ac/decli-0.6.2.tar.gz", hash = "sha256:36f71eb55fd0093895efb4f416ec32b7f6e00147dda448e3365cf73ceab42d6f", size = 7424 } +sdist = { url = "https://files.pythonhosted.org/packages/0c/59/d4ffff1dee2c8f6f2dd8f87010962e60f7b7847504d765c91ede5a466730/decli-0.6.3.tar.gz", hash = "sha256:87f9d39361adf7f16b9ca6e3b614badf7519da13092f2db3c80ca223c53c7656", size = 7564, upload-time = "2025-06-01T15:23:41.25Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bf/70/3ea48dc9e958d7d66c44c9944809181f1ca79aaef25703c023b5092d34ff/decli-0.6.2-py3-none-any.whl", hash = "sha256:2fc84106ce9a8f523ed501ca543bdb7e416c064917c12a59ebdc7f311a97b7ed", size = 7854 }, + { url = "https://files.pythonhosted.org/packages/d8/fa/ec878c28bc7f65b77e7e17af3522c9948a9711b9fa7fc4c5e3140a7e3578/decli-0.6.3-py3-none-any.whl", hash = "sha256:5152347c7bb8e3114ad65db719e5709b28d7f7f45bdb709f70167925e55640f3", size = 7989, upload-time = "2025-06-01T15:23:40.228Z" }, ] [[package]] name = "decorator" -version = "5.1.1" +version = "5.2.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/66/0c/8d907af351aa16b42caae42f9d6aa37b900c67308052d10fdce809f8d952/decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330", size = 35016 } +sdist = { url = "https://files.pythonhosted.org/packages/43/fa/6d96a0978d19e17b68d634497769987b16c8f4cd0a7a05048bec693caa6b/decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360", size = 56711, upload-time = "2025-02-24T04:41:34.073Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d5/50/83c593b07763e1161326b3b8c6686f0f4b0f24d5526546bee538c89837d6/decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186", size = 9073 }, + { url = "https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a", size = 9190, upload-time = "2025-02-24T04:41:32.565Z" }, ] [[package]] name = "defusedxml" version = "0.7.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0f/d5/c66da9b79e5bdb124974bfe172b4daf3c984ebd9c2a06e2b8a4dc7331c72/defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", size = 75520 } +sdist = { url = "https://files.pythonhosted.org/packages/0f/d5/c66da9b79e5bdb124974bfe172b4daf3c984ebd9c2a06e2b8a4dc7331c72/defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", size = 75520, upload-time = "2021-03-08T10:59:26.269Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61", size = 25604 }, + { url = "https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61", size = 25604, upload-time = "2021-03-08T10:59:24.45Z" }, ] [[package]] name = "depinfo" version = "2.2.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/df/f1/67444327ca23ca2eb511f4ab051cdf3f8ef2ad13cd75082701bd7c28aeeb/depinfo-2.2.0.tar.gz", hash = "sha256:e0971be11519a823b126c875e17ad3ad8adaa6a86737395b9dbcef3ca0e77b0c", size = 14265 } +sdist = { url = "https://files.pythonhosted.org/packages/df/f1/67444327ca23ca2eb511f4ab051cdf3f8ef2ad13cd75082701bd7c28aeeb/depinfo-2.2.0.tar.gz", hash = "sha256:e0971be11519a823b126c875e17ad3ad8adaa6a86737395b9dbcef3ca0e77b0c", size = 14265, upload-time = "2022-09-07T16:27:51.392Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1f/10/5fe7a7778cc8a701373662f99393f443541353018d3cf2bf6c8f91b032d6/depinfo-2.2.0-py3-none-any.whl", hash = "sha256:3d9ba933e7a9d718b9915f75c844a38c5603cd3cdba1816ab95e0b148b100d8f", size = 24025 }, + { url = "https://files.pythonhosted.org/packages/1f/10/5fe7a7778cc8a701373662f99393f443541353018d3cf2bf6c8f91b032d6/depinfo-2.2.0-py3-none-any.whl", hash = "sha256:3d9ba933e7a9d718b9915f75c844a38c5603cd3cdba1816ab95e0b148b100d8f", size = 24025, upload-time = "2022-09-07T16:27:49.813Z" }, ] [[package]] name = "dill" -version = "0.3.9" +version = "0.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/70/43/86fe3f9e130c4137b0f1b50784dd70a5087b911fe07fa81e53e0c4c47fea/dill-0.3.9.tar.gz", hash = "sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c", size = 187000 } +sdist = { url = "https://files.pythonhosted.org/packages/12/80/630b4b88364e9a8c8c5797f4602d0f76ef820909ee32f0bacb9f90654042/dill-0.4.0.tar.gz", hash = "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0", size = 186976, upload-time = "2025-04-16T00:41:48.867Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/46/d1/e73b6ad76f0b1fb7f23c35c6d95dbc506a9c8804f43dda8cb5b0fa6331fd/dill-0.3.9-py3-none-any.whl", hash = "sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a", size = 119418 }, + { url = "https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049", size = 119668, upload-time = "2025-04-16T00:41:47.671Z" }, ] [[package]] name = "diskcache" version = "5.6.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3f/21/1c1ffc1a039ddcc459db43cc108658f32c57d271d7289a2794e401d0fdb6/diskcache-5.6.3.tar.gz", hash = "sha256:2c3a3fa2743d8535d832ec61c2054a1641f41775aa7c556758a109941e33e4fc", size = 67916 } +sdist = { url = "https://files.pythonhosted.org/packages/3f/21/1c1ffc1a039ddcc459db43cc108658f32c57d271d7289a2794e401d0fdb6/diskcache-5.6.3.tar.gz", hash = "sha256:2c3a3fa2743d8535d832ec61c2054a1641f41775aa7c556758a109941e33e4fc", size = 67916, upload-time = "2023-08-31T06:12:00.316Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3f/27/4570e78fc0bf5ea0ca45eb1de3818a23787af9b390c0b0a0033a1b8236f9/diskcache-5.6.3-py3-none-any.whl", hash = "sha256:5e31b2d5fbad117cc363ebaf6b689474db18a1f6438bc82358b024abd4c2ca19", size = 45550 }, + { url = "https://files.pythonhosted.org/packages/3f/27/4570e78fc0bf5ea0ca45eb1de3818a23787af9b390c0b0a0033a1b8236f9/diskcache-5.6.3-py3-none-any.whl", hash = "sha256:5e31b2d5fbad117cc363ebaf6b689474db18a1f6438bc82358b024abd4c2ca19", size = 45550, upload-time = "2023-08-31T06:11:58.822Z" }, ] [[package]] -name = "et-xmlfile" -version = "2.0.0" +name = "distlib" +version = "0.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d3/38/af70d7ab1ae9d4da450eeec1fa3918940a5fafb9055e934af8d6eb0c2313/et_xmlfile-2.0.0.tar.gz", hash = "sha256:dab3f4764309081ce75662649be815c4c9081e88f0837825f90fd28317d4da54", size = 17234 } +sdist = { url = "https://files.pythonhosted.org/packages/96/8e/709914eb2b5749865801041647dc7f4e6d00b549cfe88b65ca192995f07c/distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d", size = 614605, upload-time = "2025-07-17T16:52:00.465Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/8b/5fe2cc11fee489817272089c4203e679c63b570a5aaeb18d852ae3cbba6a/et_xmlfile-2.0.0-py3-none-any.whl", hash = "sha256:7a91720bc756843502c3b7504c77b8fe44217c85c537d85037f0f536151b2caa", size = 18059 }, + { url = "https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16", size = 469047, upload-time = "2025-07-17T16:51:58.613Z" }, ] [[package]] -name = "exceptiongroup" -version = "1.2.2" +name = "donfig" +version = "0.8.1.post1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/25/71/80cc718ff6d7abfbabacb1f57aaa42e9c1552bfdd01e64ddd704e4a03638/donfig-0.8.1.post1.tar.gz", hash = "sha256:3bef3413a4c1c601b585e8d297256d0c1470ea012afa6e8461dc28bfb7c23f52", size = 19506, upload-time = "2024-05-23T14:14:31.513Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/d5/c5db1ea3394c6e1732fb3286b3bd878b59507a8f77d32a2cebda7d7b7cd4/donfig-0.8.1.post1-py3-none-any.whl", hash = "sha256:2a3175ce74a06109ff9307d90a230f81215cbac9a751f4d1c6194644b8204f9d", size = 21592, upload-time = "2024-05-23T14:13:55.283Z" }, +] + +[[package]] +name = "et-xmlfile" +version = "2.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883 } +sdist = { url = "https://files.pythonhosted.org/packages/d3/38/af70d7ab1ae9d4da450eeec1fa3918940a5fafb9055e934af8d6eb0c2313/et_xmlfile-2.0.0.tar.gz", hash = "sha256:dab3f4764309081ce75662649be815c4c9081e88f0837825f90fd28317d4da54", size = 17234, upload-time = "2024-10-25T17:25:40.039Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 }, + { url = "https://files.pythonhosted.org/packages/c1/8b/5fe2cc11fee489817272089c4203e679c63b570a5aaeb18d852ae3cbba6a/et_xmlfile-2.0.0-py3-none-any.whl", hash = "sha256:7a91720bc756843502c3b7504c77b8fe44217c85c537d85037f0f536151b2caa", size = 18059, upload-time = "2024-10-25T17:25:39.051Z" }, ] [[package]] name = "executing" -version = "2.1.0" +version = "2.2.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8c/e3/7d45f492c2c4a0e8e0fad57d081a7c8a0286cdd86372b070cca1ec0caa1e/executing-2.1.0.tar.gz", hash = "sha256:8ea27ddd260da8150fa5a708269c4a10e76161e2496ec3e587da9e3c0fe4b9ab", size = 977485 } +sdist = { url = "https://files.pythonhosted.org/packages/cc/28/c14e053b6762b1044f34a13aab6859bbf40456d37d23aa286ac24cfd9a5d/executing-2.2.1.tar.gz", hash = "sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4", size = 1129488, upload-time = "2025-09-01T09:48:10.866Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b5/fd/afcd0496feca3276f509df3dbd5dae726fcc756f1a08d9e25abe1733f962/executing-2.1.0-py2.py3-none-any.whl", hash = "sha256:8d63781349375b5ebccc3142f4b30350c0cd9c79f921cde38be2be4637e98eaf", size = 25805 }, + { url = "https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl", hash = "sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017", size = 28317, upload-time = "2025-09-01T09:48:08.5Z" }, ] [[package]] @@ -710,148 +843,198 @@ dependencies = [ { name = "loguru" }, { name = "pandas" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/76/f2/1575a1233ee470cdc52efa1ad5e00050bb39b3f7ebdb3813fba42035e7c3/fast_bioservices-0.3.9.tar.gz", hash = "sha256:4094d5963b5baab2f7d3a02a74d1d841e83670341065ea0ed0d1f09ba658bf05", size = 47042 } +sdist = { url = "https://files.pythonhosted.org/packages/76/f2/1575a1233ee470cdc52efa1ad5e00050bb39b3f7ebdb3813fba42035e7c3/fast_bioservices-0.3.9.tar.gz", hash = "sha256:4094d5963b5baab2f7d3a02a74d1d841e83670341065ea0ed0d1f09ba658bf05", size = 47042, upload-time = "2024-12-04T19:32:29.458Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/48/6c/6033e67a7d734ba90ff186e5404f78b0e3b59ae46e78bec11764ae50c508/fast_bioservices-0.3.9-py3-none-any.whl", hash = "sha256:f041a30300d4de5c7d2d5e0405b8505e7a7f79248e986ecf45ddb3473d7c4d8f", size = 22687 }, + { url = "https://files.pythonhosted.org/packages/48/6c/6033e67a7d734ba90ff186e5404f78b0e3b59ae46e78bec11764ae50c508/fast_bioservices-0.3.9-py3-none-any.whl", hash = "sha256:f041a30300d4de5c7d2d5e0405b8505e7a7f79248e986ecf45ddb3473d7c4d8f", size = 22687, upload-time = "2024-12-04T19:32:28.023Z" }, ] [[package]] name = "fastjsonschema" -version = "2.21.1" +version = "2.21.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/b5/23b216d9d985a956623b6bd12d4086b60f0059b27799f23016af04a74ea1/fastjsonschema-2.21.2.tar.gz", hash = "sha256:b1eb43748041c880796cd077f1a07c3d94e93ae84bba5ed36800a33554ae05de", size = 374130, upload-time = "2025-08-14T18:49:36.666Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl", hash = "sha256:1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463", size = 24024, upload-time = "2025-08-14T18:49:34.776Z" }, +] + +[[package]] +name = "filelock" +version = "3.19.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8b/50/4b769ce1ac4071a1ef6d86b1a3fb56cdc3a37615e8c5519e1af96cdac366/fastjsonschema-2.21.1.tar.gz", hash = "sha256:794d4f0a58f848961ba16af7b9c85a3e88cd360df008c59aac6fc5ae9323b5d4", size = 373939 } +sdist = { url = "https://files.pythonhosted.org/packages/40/bb/0ab3e58d22305b6f5440629d20683af28959bf793d98d11950e305c1c326/filelock-3.19.1.tar.gz", hash = "sha256:66eda1888b0171c998b35be2bcc0f6d75c388a7ce20c3f3f37aa8e96c2dddf58", size = 17687, upload-time = "2025-08-14T16:56:03.016Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/90/2b/0817a2b257fe88725c25589d89aec060581aabf668707a8d03b2e9e0cb2a/fastjsonschema-2.21.1-py3-none-any.whl", hash = "sha256:c9e5b7e908310918cf494a434eeb31384dd84a98b57a30bcb1f535015b554667", size = 23924 }, + { url = "https://files.pythonhosted.org/packages/42/14/42b2651a2f46b022ccd948bca9f2d5af0fd8929c4eec235b8d6d844fbe67/filelock-3.19.1-py3-none-any.whl", hash = "sha256:d38e30481def20772f5baf097c122c3babc4fcdb7e14e57049eb9d88c6dc017d", size = 15988, upload-time = "2025-08-14T16:56:01.633Z" }, ] [[package]] name = "fonttools" -version = "4.54.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/11/1d/70b58e342e129f9c0ce030029fb4b2b0670084bbbfe1121d008f6a1e361c/fonttools-4.54.1.tar.gz", hash = "sha256:957f669d4922f92c171ba01bef7f29410668db09f6c02111e22b2bce446f3285", size = 3463867 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/db/f9/285c9a2d0e86b9bf2babfe19bec00502361fda56cea144d6a269ab9a32e6/fonttools-4.54.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7ed7ee041ff7b34cc62f07545e55e1468808691dddfd315d51dd82a6b37ddef2", size = 2766970 }, - { url = "https://files.pythonhosted.org/packages/2f/9a/9d899e7ae55b0dd30632e6ca36c0f5fa1205b1b096ec171c9be903673058/fonttools-4.54.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41bb0b250c8132b2fcac148e2e9198e62ff06f3cc472065dff839327945c5882", size = 2254639 }, - { url = "https://files.pythonhosted.org/packages/16/6f/b99e0c347732fb003077a2cff38c26f381969b74329aa5597e344d540fe1/fonttools-4.54.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7965af9b67dd546e52afcf2e38641b5be956d68c425bef2158e95af11d229f10", size = 4574346 }, - { url = "https://files.pythonhosted.org/packages/e5/12/9a45294a7c4520cc32936edd15df1d5c24af701d2f5f51070a9a43d7664b/fonttools-4.54.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:278913a168f90d53378c20c23b80f4e599dca62fbffae4cc620c8eed476b723e", size = 4630045 }, - { url = "https://files.pythonhosted.org/packages/64/52/ba4f00eb6003e4089264cd9ce126cddec2b39c78f1ab01be9dc389a197ca/fonttools-4.54.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0e88e3018ac809b9662615072dcd6b84dca4c2d991c6d66e1970a112503bba7e", size = 4569527 }, - { url = "https://files.pythonhosted.org/packages/41/ff/85f93a14c8acf978f332508f980dcaff5ed5f0cf284371eb101a78f0b1f4/fonttools-4.54.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4aa4817f0031206e637d1e685251ac61be64d1adef111060df84fdcbc6ab6c44", size = 4741677 }, - { url = "https://files.pythonhosted.org/packages/6f/f0/06ea7d9f8b7b6d4758a50271517db04039c4c6da8fa0475d417e005624d0/fonttools-4.54.1-cp310-cp310-win32.whl", hash = "sha256:7e3b7d44e18c085fd8c16dcc6f1ad6c61b71ff463636fcb13df7b1b818bd0c02", size = 2166797 }, - { url = "https://files.pythonhosted.org/packages/71/73/545c817e34b8c34585291951722e1a5ae579380deb009576d9d244b13ab0/fonttools-4.54.1-cp310-cp310-win_amd64.whl", hash = "sha256:dd9cc95b8d6e27d01e1e1f1fae8559ef3c02c76317da650a19047f249acd519d", size = 2210552 }, - { url = "https://files.pythonhosted.org/packages/aa/2c/8b5d82fe2d9c7f260fb73121418f5e07d4e38c329ea3886a5b0e55586113/fonttools-4.54.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5419771b64248484299fa77689d4f3aeed643ea6630b2ea750eeab219588ba20", size = 2768112 }, - { url = "https://files.pythonhosted.org/packages/37/2e/f94118b92f7b6a9ec93840101b64bfdd09f295b266133857e8e852a5c35c/fonttools-4.54.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:301540e89cf4ce89d462eb23a89464fef50915255ece765d10eee8b2bf9d75b2", size = 2254739 }, - { url = "https://files.pythonhosted.org/packages/45/4b/8a32f56a13e78256192f77d6b65583c43538c7955f5420887bb574b91ddf/fonttools-4.54.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76ae5091547e74e7efecc3cbf8e75200bc92daaeb88e5433c5e3e95ea8ce5aa7", size = 4879772 }, - { url = "https://files.pythonhosted.org/packages/96/13/748b7f7239893ff0796de11074b0ad8aa4c3da2d9f4d79a128b0b16147f3/fonttools-4.54.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82834962b3d7c5ca98cb56001c33cf20eb110ecf442725dc5fdf36d16ed1ab07", size = 4927686 }, - { url = "https://files.pythonhosted.org/packages/7c/82/91bc5a378b4a0593fa90ea706f68ce7e9e871c6873e0d91e134d107758db/fonttools-4.54.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d26732ae002cc3d2ecab04897bb02ae3f11f06dd7575d1df46acd2f7c012a8d8", size = 4890789 }, - { url = "https://files.pythonhosted.org/packages/ea/ca/82be5d4f8b78405cdb3f7f3f1316af5e8db93216121f19da9f684a35beee/fonttools-4.54.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:58974b4987b2a71ee08ade1e7f47f410c367cdfc5a94fabd599c88165f56213a", size = 5061351 }, - { url = "https://files.pythonhosted.org/packages/da/2f/fd6e1b01c80c473c3ac52492dcf8d26cdf5f4a89b4f30875ecfbda55e7ff/fonttools-4.54.1-cp311-cp311-win32.whl", hash = "sha256:ab774fa225238986218a463f3fe151e04d8c25d7de09df7f0f5fce27b1243dbc", size = 2166210 }, - { url = "https://files.pythonhosted.org/packages/63/f1/3a081cd047d83b5966cb0d7ef3fea929ee6eddeb94d8fbfdb2a19bd60cc7/fonttools-4.54.1-cp311-cp311-win_amd64.whl", hash = "sha256:07e005dc454eee1cc60105d6a29593459a06321c21897f769a281ff2d08939f6", size = 2211946 }, - { url = "https://files.pythonhosted.org/packages/27/b6/f9d365932dcefefdcc794985f8846471e60932070c557e0f66ed195fccec/fonttools-4.54.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:54471032f7cb5fca694b5f1a0aaeba4af6e10ae989df408e0216f7fd6cdc405d", size = 2761873 }, - { url = "https://files.pythonhosted.org/packages/67/9d/cfbfe36e5061a8f68b154454ba2304eb01f40d4ba9b63e41d9058909baed/fonttools-4.54.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8fa92cb248e573daab8d032919623cc309c005086d743afb014c836636166f08", size = 2251828 }, - { url = "https://files.pythonhosted.org/packages/90/41/5573e074739efd9227dd23647724f01f6f07ad062fe09d02e91c5549dcf7/fonttools-4.54.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a911591200114969befa7f2cb74ac148bce5a91df5645443371aba6d222e263", size = 4792544 }, - { url = "https://files.pythonhosted.org/packages/08/07/aa85cc62abcc940b25d14b542cf585eebf4830032a7f6a1395d696bb3231/fonttools-4.54.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93d458c8a6a354dc8b48fc78d66d2a8a90b941f7fec30e94c7ad9982b1fa6bab", size = 4875892 }, - { url = "https://files.pythonhosted.org/packages/47/23/c5726c2615446c498a976bed21c35a242a97eee39930a2655d616ca885cc/fonttools-4.54.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5eb2474a7c5be8a5331146758debb2669bf5635c021aee00fd7c353558fc659d", size = 4769822 }, - { url = "https://files.pythonhosted.org/packages/8f/7b/87f7f7d35e0732ac67422dfa6f05e2b568fb6ca2dcd7f3e4f500293cfd75/fonttools-4.54.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c9c563351ddc230725c4bdf7d9e1e92cbe6ae8553942bd1fb2b2ff0884e8b714", size = 5029455 }, - { url = "https://files.pythonhosted.org/packages/e0/09/241aa498587889576838aa73c78d22b70ce06970807a5475d372baa7ccb7/fonttools-4.54.1-cp312-cp312-win32.whl", hash = "sha256:fdb062893fd6d47b527d39346e0c5578b7957dcea6d6a3b6794569370013d9ac", size = 2154411 }, - { url = "https://files.pythonhosted.org/packages/b9/0a/a57caaff3bc880779317cb157e5b49dc47fad54effe027016abd355b0651/fonttools-4.54.1-cp312-cp312-win_amd64.whl", hash = "sha256:e4564cf40cebcb53f3dc825e85910bf54835e8a8b6880d59e5159f0f325e637e", size = 2200412 }, - { url = "https://files.pythonhosted.org/packages/57/5e/de2e6e51cb6894f2f2bc2641f6c845561361b622e96df3cca04df77222c9/fonttools-4.54.1-py3-none-any.whl", hash = "sha256:37cddd62d83dc4f72f7c3f3c2bcf2697e89a30efb152079896544a93907733bd", size = 1096920 }, +version = "4.59.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0d/a5/fba25f9fbdab96e26dedcaeeba125e5f05a09043bf888e0305326e55685b/fonttools-4.59.2.tar.gz", hash = "sha256:e72c0749b06113f50bcb80332364c6be83a9582d6e3db3fe0b280f996dc2ef22", size = 3540889, upload-time = "2025-08-27T16:40:30.97Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/53/742fcd750ae0bdc74de4c0ff923111199cc2f90a4ee87aaddad505b6f477/fonttools-4.59.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:511946e8d7ea5c0d6c7a53c4cb3ee48eda9ab9797cd9bf5d95829a398400354f", size = 2774961, upload-time = "2025-08-27T16:38:47.536Z" }, + { url = "https://files.pythonhosted.org/packages/57/2a/976f5f9fa3b4dd911dc58d07358467bec20e813d933bc5d3db1a955dd456/fonttools-4.59.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8e5e2682cf7be766d84f462ba8828d01e00c8751a8e8e7ce12d7784ccb69a30d", size = 2344690, upload-time = "2025-08-27T16:38:49.723Z" }, + { url = "https://files.pythonhosted.org/packages/c1/8f/b7eefc274fcf370911e292e95565c8253b0b87c82a53919ab3c795a4f50e/fonttools-4.59.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5729e12a982dba3eeae650de48b06f3b9ddb51e9aee2fcaf195b7d09a96250e2", size = 5026910, upload-time = "2025-08-27T16:38:51.904Z" }, + { url = "https://files.pythonhosted.org/packages/69/95/864726eaa8f9d4e053d0c462e64d5830ec7c599cbdf1db9e40f25ca3972e/fonttools-4.59.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c52694eae5d652361d59ecdb5a2246bff7cff13b6367a12da8499e9df56d148d", size = 4971031, upload-time = "2025-08-27T16:38:53.676Z" }, + { url = "https://files.pythonhosted.org/packages/24/4c/b8c4735ebdea20696277c70c79e0de615dbe477834e5a7c2569aa1db4033/fonttools-4.59.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f1f1bbc23ba1312bd8959896f46f667753b90216852d2a8cfa2d07e0cb234144", size = 5006112, upload-time = "2025-08-27T16:38:55.69Z" }, + { url = "https://files.pythonhosted.org/packages/3b/23/f9ea29c292aa2fc1ea381b2e5621ac436d5e3e0a5dee24ffe5404e58eae8/fonttools-4.59.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1a1bfe5378962825dabe741720885e8b9ae9745ec7ecc4a5ec1f1ce59a6062bf", size = 5117671, upload-time = "2025-08-27T16:38:58.984Z" }, + { url = "https://files.pythonhosted.org/packages/ba/07/cfea304c555bf06e86071ff2a3916bc90f7c07ec85b23bab758d4908c33d/fonttools-4.59.2-cp311-cp311-win32.whl", hash = "sha256:e937790f3c2c18a1cbc7da101550a84319eb48023a715914477d2e7faeaba570", size = 2218157, upload-time = "2025-08-27T16:39:00.75Z" }, + { url = "https://files.pythonhosted.org/packages/d7/de/35d839aa69db737a3f9f3a45000ca24721834d40118652a5775d5eca8ebb/fonttools-4.59.2-cp311-cp311-win_amd64.whl", hash = "sha256:9836394e2f4ce5f9c0a7690ee93bd90aa1adc6b054f1a57b562c5d242c903104", size = 2265846, upload-time = "2025-08-27T16:39:02.453Z" }, + { url = "https://files.pythonhosted.org/packages/ba/3d/1f45db2df51e7bfa55492e8f23f383d372200be3a0ded4bf56a92753dd1f/fonttools-4.59.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:82906d002c349cad647a7634b004825a7335f8159d0d035ae89253b4abf6f3ea", size = 2769711, upload-time = "2025-08-27T16:39:04.423Z" }, + { url = "https://files.pythonhosted.org/packages/29/df/cd236ab32a8abfd11558f296e064424258db5edefd1279ffdbcfd4fd8b76/fonttools-4.59.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a10c1bd7644dc58f8862d8ba0cf9fb7fef0af01ea184ba6ce3f50ab7dfe74d5a", size = 2340225, upload-time = "2025-08-27T16:39:06.143Z" }, + { url = "https://files.pythonhosted.org/packages/98/12/b6f9f964fe6d4b4dd4406bcbd3328821c3de1f909ffc3ffa558fe72af48c/fonttools-4.59.2-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:738f31f23e0339785fd67652a94bc69ea49e413dfdb14dcb8c8ff383d249464e", size = 4912766, upload-time = "2025-08-27T16:39:08.138Z" }, + { url = "https://files.pythonhosted.org/packages/73/78/82bde2f2d2c306ef3909b927363170b83df96171f74e0ccb47ad344563cd/fonttools-4.59.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ec99f9bdfee9cdb4a9172f9e8fd578cce5feb231f598909e0aecf5418da4f25", size = 4955178, upload-time = "2025-08-27T16:39:10.094Z" }, + { url = "https://files.pythonhosted.org/packages/92/77/7de766afe2d31dda8ee46d7e479f35c7d48747e558961489a2d6e3a02bd4/fonttools-4.59.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0476ea74161322e08c7a982f83558a2b81b491509984523a1a540baf8611cc31", size = 4897898, upload-time = "2025-08-27T16:39:12.087Z" }, + { url = "https://files.pythonhosted.org/packages/c5/77/ce0e0b905d62a06415fda9f2b2e109a24a5db54a59502b769e9e297d2242/fonttools-4.59.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:95922a922daa1f77cc72611747c156cfb38030ead72436a2c551d30ecef519b9", size = 5049144, upload-time = "2025-08-27T16:39:13.84Z" }, + { url = "https://files.pythonhosted.org/packages/d9/ea/870d93aefd23fff2e07cbeebdc332527868422a433c64062c09d4d5e7fe6/fonttools-4.59.2-cp312-cp312-win32.whl", hash = "sha256:39ad9612c6a622726a6a130e8ab15794558591f999673f1ee7d2f3d30f6a3e1c", size = 2206473, upload-time = "2025-08-27T16:39:15.854Z" }, + { url = "https://files.pythonhosted.org/packages/61/c4/e44bad000c4a4bb2e9ca11491d266e857df98ab6d7428441b173f0fe2517/fonttools-4.59.2-cp312-cp312-win_amd64.whl", hash = "sha256:980fd7388e461b19a881d35013fec32c713ffea1fc37aef2f77d11f332dfd7da", size = 2254706, upload-time = "2025-08-27T16:39:17.893Z" }, + { url = "https://files.pythonhosted.org/packages/13/7b/d0d3b9431642947b5805201fbbbe938a47b70c76685ef1f0cb5f5d7140d6/fonttools-4.59.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:381bde13216ba09489864467f6bc0c57997bd729abfbb1ce6f807ba42c06cceb", size = 2761563, upload-time = "2025-08-27T16:39:20.286Z" }, + { url = "https://files.pythonhosted.org/packages/76/be/fc5fe58dd76af7127b769b68071dbc32d4b95adc8b58d1d28d42d93c90f2/fonttools-4.59.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f33839aa091f7eef4e9078f5b7ab1b8ea4b1d8a50aeaef9fdb3611bba80869ec", size = 2335671, upload-time = "2025-08-27T16:39:22.027Z" }, + { url = "https://files.pythonhosted.org/packages/f2/9f/bf231c2a3fac99d1d7f1d89c76594f158693f981a4aa02be406e9f036832/fonttools-4.59.2-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6235fc06bcbdb40186f483ba9d5d68f888ea68aa3c8dac347e05a7c54346fbc8", size = 4893967, upload-time = "2025-08-27T16:39:23.664Z" }, + { url = "https://files.pythonhosted.org/packages/26/a9/d46d2ad4fcb915198504d6727f83aa07f46764c64f425a861aa38756c9fd/fonttools-4.59.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:83ad6e5d06ef3a2884c4fa6384a20d6367b5cfe560e3b53b07c9dc65a7020e73", size = 4951986, upload-time = "2025-08-27T16:39:25.379Z" }, + { url = "https://files.pythonhosted.org/packages/07/90/1cc8d7dd8f707dfeeca472b82b898d3add0ebe85b1f645690dcd128ee63f/fonttools-4.59.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d029804c70fddf90be46ed5305c136cae15800a2300cb0f6bba96d48e770dde0", size = 4891630, upload-time = "2025-08-27T16:39:27.494Z" }, + { url = "https://files.pythonhosted.org/packages/d8/04/f0345b0d9fe67d65aa8d3f2d4cbf91d06f111bc7b8d802e65914eb06194d/fonttools-4.59.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:95807a3b5e78f2714acaa26a33bc2143005cc05c0217b322361a772e59f32b89", size = 5035116, upload-time = "2025-08-27T16:39:29.406Z" }, + { url = "https://files.pythonhosted.org/packages/d7/7d/5ba5eefffd243182fbd067cdbfeb12addd4e5aec45011b724c98a344ea33/fonttools-4.59.2-cp313-cp313-win32.whl", hash = "sha256:b3ebda00c3bb8f32a740b72ec38537d54c7c09f383a4cfefb0b315860f825b08", size = 2204907, upload-time = "2025-08-27T16:39:31.42Z" }, + { url = "https://files.pythonhosted.org/packages/ea/a9/be7219fc64a6026cc0aded17fa3720f9277001c185434230bd351bf678e6/fonttools-4.59.2-cp313-cp313-win_amd64.whl", hash = "sha256:a72155928d7053bbde499d32a9c77d3f0f3d29ae72b5a121752481bcbd71e50f", size = 2253742, upload-time = "2025-08-27T16:39:33.079Z" }, + { url = "https://files.pythonhosted.org/packages/65/a4/d2f7be3c86708912c02571db0b550121caab8cd88a3c0aacb9cfa15ea66e/fonttools-4.59.2-py3-none-any.whl", hash = "sha256:8bd0f759020e87bb5d323e6283914d9bf4ae35a7307dafb2cbd1e379e720ad37", size = 1132315, upload-time = "2025-08-27T16:40:28.984Z" }, ] [[package]] name = "fqdn" version = "1.5.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/30/3e/a80a8c077fd798951169626cde3e239adeba7dab75deb3555716415bd9b0/fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f", size = 6015 } +sdist = { url = "https://files.pythonhosted.org/packages/30/3e/a80a8c077fd798951169626cde3e239adeba7dab75deb3555716415bd9b0/fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f", size = 6015, upload-time = "2021-03-11T07:16:29.08Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014", size = 9121 }, + { url = "https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014", size = 9121, upload-time = "2021-03-11T07:16:28.351Z" }, ] [[package]] name = "future" version = "1.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a7/b2/4140c69c6a66432916b26158687e821ba631a4c9273c474343badf84d3ba/future-1.0.0.tar.gz", hash = "sha256:bd2968309307861edae1458a4f8a4f3598c03be43b97521076aebf5d94c07b05", size = 1228490 } +sdist = { url = "https://files.pythonhosted.org/packages/a7/b2/4140c69c6a66432916b26158687e821ba631a4c9273c474343badf84d3ba/future-1.0.0.tar.gz", hash = "sha256:bd2968309307861edae1458a4f8a4f3598c03be43b97521076aebf5d94c07b05", size = 1228490, upload-time = "2024-02-21T11:52:38.461Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/da/71/ae30dadffc90b9006d77af76b393cb9dfbfc9629f339fc1574a1c52e6806/future-1.0.0-py3-none-any.whl", hash = "sha256:929292d34f5872e70396626ef385ec22355a1fae8ad29e1a734c3e43f9fbc216", size = 491326 }, + { url = "https://files.pythonhosted.org/packages/da/71/ae30dadffc90b9006d77af76b393cb9dfbfc9629f339fc1574a1c52e6806/future-1.0.0-py3-none-any.whl", hash = "sha256:929292d34f5872e70396626ef385ec22355a1fae8ad29e1a734c3e43f9fbc216", size = 491326, upload-time = "2024-02-21T11:52:35.956Z" }, ] [[package]] name = "gurobipy" -version = "11.0.3" +version = "12.0.3" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/94/af/4fec1f4f82d8ec7a48d16905d5e4dd326273a5b43ee206640c7cb9234af5/gurobipy-11.0.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ec3a8da22c8e818095bbe86ed0b71f9f3712272afb994edc04dc3c82654c7542", size = 10754812 }, - { url = "https://files.pythonhosted.org/packages/eb/f9/b94cf5aaaed2192da968bcbe7ce121c7862b309f548d4ec99e21cfcf0c26/gurobipy-11.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:623ea11104b50b574d7c73ae19e87131431cd4d33adcaf0d408a7e44cb73ed43", size = 27414829 }, - { url = "https://files.pythonhosted.org/packages/27/28/1006619ca69b3813776c57be979f0cddbf259e4099f9d971492965c35dd7/gurobipy-11.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2074a21e9e78b62a84e3b123a8d44566562667b3d0e6ae5543ccb45207d44de6", size = 13443717 }, - { url = "https://files.pythonhosted.org/packages/14/c3/d3891d4e0dc10e745a4769c1541210168852b1e54c87b9c8c3919981aba4/gurobipy-11.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:ec84cd537a9d1b392ffd09cb03e617c6cc69322f5e195c0c87328cf592482123", size = 10323518 }, - { url = "https://files.pythonhosted.org/packages/1e/ba/dd7d8f299a3a87ae5bd5553b82199851e6e5e7b6fcf8528570b05d343610/gurobipy-11.0.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:138b4be8fb42d494b8484bd4cfa99ea1e511e8860cdb1171349f4fce06d9aa01", size = 10784430 }, - { url = "https://files.pythonhosted.org/packages/b9/68/7ccd72bf75db54c70ec563f5f700119ea290c9a6ccac9f3191295e4739f5/gurobipy-11.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:84c58e164c90fc1de8bc0aac8ad25a82b4a9d3079b5064735822cecf552b1b26", size = 27422010 }, - { url = "https://files.pythonhosted.org/packages/af/53/8b5194b41760718a8cfb01010dcab5a8f464468fffacceb256df8aefa906/gurobipy-11.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d8eed5ca4831d1f10b08cd701f75483b27810734750d414a5b3cb6e4ba4c17f3", size = 13446177 }, - { url = "https://files.pythonhosted.org/packages/28/41/c61b4b096a093479eb45292ec7a5d127f088a92d4748faec76e4fcd2443e/gurobipy-11.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9e57508f7d7a8ef154767894c693273d94bed771fa300677ae74892fde7dfc57", size = 10324769 }, - { url = "https://files.pythonhosted.org/packages/19/71/d21d15318a6f400f331e940924910aa5140da55dd84813bd9f8bdecaf707/gurobipy-11.0.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:05700979469511aedfcb4d0136c161077d085393b6a449c98e9ff7818747279c", size = 10709232 }, - { url = "https://files.pythonhosted.org/packages/ec/74/d2523173f9eb8ec66a7d892a49ca6899d75acddac418f8c81cd50d4b420a/gurobipy-11.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b752a8a4d898a3cc59b0670aa449dee8e2159d4f420f30033baf96f14a36516d", size = 27267858 }, - { url = "https://files.pythonhosted.org/packages/73/5a/4c764ccd1e9bcef3d01729af0811915f3fb36e72b544e5caf477b1dc545f/gurobipy-11.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d08a69a9884b2c7ab843c9967b44770c17c73ac5726db7a8794ae85d7c1fc446", size = 13257275 }, - { url = "https://files.pythonhosted.org/packages/f2/54/b4eea516b5e318c3522456f8a26a2fc6e8c9c657e0ed06ce5ec4f7faca4d/gurobipy-11.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:74fa0d9bace48bc0f25426b5cd70addb02a13b5ea1645494cad073a32c9ec2c4", size = 10296203 }, + { url = "https://files.pythonhosted.org/packages/1b/fc/e52692f0dc69cf1827af596480695d3097431eb570713f24c2a487d13a73/gurobipy-12.0.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:03a833da391549a85e41dbde6339deea8f19cfa556efc887cab878207ffb318d", size = 12329884, upload-time = "2025-07-15T07:18:03.378Z" }, + { url = "https://files.pythonhosted.org/packages/08/27/ed8aaf6e67ff4e876a036acb89eb56722b2405c817e7a2155d0c8ecc3638/gurobipy-12.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f980145d84bc739a2d28a23160b9c4c8ea7ba9cdaf8a8e0d7c98d9fb4b8222ae", size = 62770251, upload-time = "2025-07-15T07:18:55.313Z" }, + { url = "https://files.pythonhosted.org/packages/15/15/f700f39f6d3e51e7d03371e9392e851ddbbeea90b09d8de99e3e0ba20b66/gurobipy-12.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2671dfa6c8fa2feb4af6efaaf2e15a355556f4f67f8b4a1787c9854be8044aa0", size = 14487912, upload-time = "2025-07-15T07:19:05.405Z" }, + { url = "https://files.pythonhosted.org/packages/5b/f8/508e7c1de7c39086b35cad0d6e851899d9bc1878200cb7e3db048f3253ba/gurobipy-12.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:3304f422922de75f8cb111c64515e58232d8c853205db523cc6bdcc4209c7e94", size = 11235248, upload-time = "2025-07-15T07:19:12.939Z" }, + { url = "https://files.pythonhosted.org/packages/6f/bb/b3784497115c64c2bd122cc9d411f167026d4ec42a26b1ff3c43a779275d/gurobipy-12.0.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:020f23277f630e079eac114385eabd1bd9fb4ac22f8796ed5ba6d915ce4f141b", size = 12222234, upload-time = "2025-07-15T07:19:24.64Z" }, + { url = "https://files.pythonhosted.org/packages/18/ea/c065984de5287c99fd30ee8d700fd78f83692e992471f9667ab5d36612b9/gurobipy-12.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:72bbf544bc05060bb93909b79715ace4c0f416198f7622a985cabb9e8e99aa1c", size = 62583866, upload-time = "2025-07-15T07:20:17.576Z" }, + { url = "https://files.pythonhosted.org/packages/9b/8b/2b9f26e4e19a258229b8a8ffc377ca372cc2059a22a0a7c67572efe308d8/gurobipy-12.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b3f971caf270f671b6ffcf5b937b3c0430a5264b0f01529dc8681d61c221f215", size = 14268480, upload-time = "2025-07-15T07:20:26.898Z" }, + { url = "https://files.pythonhosted.org/packages/26/0f/3544a323635f37cdfe1e011d2903b7ef94ba18e10224fa1419f64d0c1968/gurobipy-12.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:af18fd03d5dc3f6e5f590c372ad288b8430a6d88a5b5e66cfcd8432f86ee8650", size = 11121565, upload-time = "2025-07-15T07:20:34.576Z" }, + { url = "https://files.pythonhosted.org/packages/5e/95/f0e5b5cf85298f42482cf4e53d8114c45bb962f55195d531fe4e62b5afa1/gurobipy-12.0.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a8552e47673cb6f1fd351edf8fcad86b02f832cbfb57d90ef21e0397e96d138e", size = 12183439, upload-time = "2025-07-15T07:20:44.224Z" }, + { url = "https://files.pythonhosted.org/packages/61/6e/aea725b4143faa4eb6878414a91fa74e7871aba0ab9453803a9eeef781c2/gurobipy-12.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:be05c074141c8a126c8aaeccc41795ab091a666eabb39ca1ff98a74bde81e663", size = 62583451, upload-time = "2025-07-15T07:21:38.825Z" }, + { url = "https://files.pythonhosted.org/packages/75/47/7b9c63ce2cd85d796403b91a6d211d5c8baac7b694edd94e2151f365d6a9/gurobipy-12.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:79a333766e27fef7902ceeefbcf0279a1ca393a27a72ea62f8e301b21aa17d59", size = 14271076, upload-time = "2025-07-15T07:21:55.102Z" }, + { url = "https://files.pythonhosted.org/packages/2a/93/b10cd6112c05675fed5c817fd7933c9d4ba3a7039e42cba844a9ac09242a/gurobipy-12.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:e0f9ed55077e622021369bb9df2ca3b00c86b678792a3b1556cc59f67348fab0", size = 11111414, upload-time = "2025-07-15T07:22:05.079Z" }, ] [[package]] name = "h11" -version = "0.14.0" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, +] + +[[package]] +name = "h5netcdf" +version = "1.6.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 } +dependencies = [ + { name = "h5py" }, + { name = "packaging" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5a/a1/e3ca842fd0895fcfb21c754a18fd8cd7362d1625b3a93408c982c38f4ec1/h5netcdf-1.6.4.tar.gz", hash = "sha256:83db7e5eb9b822bed2c79050d6cf8f36ecbd1039f4252bd90fab200edcaaf67d", size = 65832, upload-time = "2025-08-05T06:26:56.707Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 }, + { url = "https://files.pythonhosted.org/packages/5b/f5/ac71e692aad076d50a0f5f073204346d5f5577daffd21bb4b72c485f8959/h5netcdf-1.6.4-py3-none-any.whl", hash = "sha256:e0018e6a918f2bef2a4aa7b470a952b8a0b5d16a5893d59bea56524cc6207fcf", size = 50683, upload-time = "2025-08-05T06:26:55.644Z" }, ] [[package]] name = "h5py" -version = "3.12.1" +version = "3.14.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/cc/0c/5c2b0a88158682aeafb10c1c2b735df5bc31f165bfe192f2ee9f2a23b5f1/h5py-3.12.1.tar.gz", hash = "sha256:326d70b53d31baa61f00b8aa5f95c2fcb9621a3ee8365d770c551a13dbbcbfdf", size = 411457 } +sdist = { url = "https://files.pythonhosted.org/packages/5d/57/dfb3c5c3f1bf5f5ef2e59a22dec4ff1f3d7408b55bfcefcfb0ea69ef21c6/h5py-3.14.0.tar.gz", hash = "sha256:2372116b2e0d5d3e5e705b7f663f7c8d96fa79a4052d250484ef91d24d6a08f4", size = 424323, upload-time = "2025-06-06T14:06:15.01Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/df/7d/b21045fbb004ad8bb6fb3be4e6ca903841722706f7130b9bba31ef2f88e3/h5py-3.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f0f1a382cbf494679c07b4371f90c70391dedb027d517ac94fa2c05299dacda", size = 3402133 }, - { url = "https://files.pythonhosted.org/packages/29/a7/3c2a33fba1da64a0846744726fd067a92fb8abb887875a0dd8e3bac8b45d/h5py-3.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cb65f619dfbdd15e662423e8d257780f9a66677eae5b4b3fc9dca70b5fd2d2a3", size = 2866436 }, - { url = "https://files.pythonhosted.org/packages/1e/d0/4bf67c3937a2437c20844165766ddd1a1817ae6b9544c3743050d8e0f403/h5py-3.12.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b15d8dbd912c97541312c0e07438864d27dbca857c5ad634de68110c6beb1c2", size = 5168596 }, - { url = "https://files.pythonhosted.org/packages/85/bc/e76f4b2096e0859225f5441d1b7f5e2041fffa19fc2c16756c67078417aa/h5py-3.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59685fe40d8c1fbbee088c88cd4da415a2f8bee5c270337dc5a1c4aa634e3307", size = 5341537 }, - { url = "https://files.pythonhosted.org/packages/99/bd/fb8ed45308bb97e04c02bd7aed324ba11e6a4bf9ed73967ca2a168e9cf92/h5py-3.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:577d618d6b6dea3da07d13cc903ef9634cde5596b13e832476dd861aaf651f3e", size = 2990575 }, - { url = "https://files.pythonhosted.org/packages/33/61/c463dc5fc02fbe019566d067a9d18746cd3c664f29c9b8b3c3f9ed025365/h5py-3.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ccd9006d92232727d23f784795191bfd02294a4f2ba68708825cb1da39511a93", size = 3410828 }, - { url = "https://files.pythonhosted.org/packages/95/9d/eb91a9076aa998bb2179d6b1788055ea09cdf9d6619cd967f1d3321ed056/h5py-3.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ad8a76557880aed5234cfe7279805f4ab5ce16b17954606cca90d578d3e713ef", size = 2872586 }, - { url = "https://files.pythonhosted.org/packages/b0/62/e2b1f9723ff713e3bd3c16dfeceec7017eadc21ef063d8b7080c0fcdc58a/h5py-3.12.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1473348139b885393125126258ae2d70753ef7e9cec8e7848434f385ae72069e", size = 5273038 }, - { url = "https://files.pythonhosted.org/packages/e1/89/118c3255d6ff2db33b062ec996a762d99ae50c21f54a8a6047ae8eda1b9f/h5py-3.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:018a4597f35092ae3fb28ee851fdc756d2b88c96336b8480e124ce1ac6fb9166", size = 5452688 }, - { url = "https://files.pythonhosted.org/packages/1d/4d/cbd3014eb78d1e449b29beba1f3293a841aa8086c6f7968c383c2c7ff076/h5py-3.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:3fdf95092d60e8130ba6ae0ef7a9bd4ade8edbe3569c13ebbaf39baefffc5ba4", size = 3006095 }, - { url = "https://files.pythonhosted.org/packages/d4/e1/ea9bfe18a3075cdc873f0588ff26ce394726047653557876d7101bf0c74e/h5py-3.12.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:06a903a4e4e9e3ebbc8b548959c3c2552ca2d70dac14fcfa650d9261c66939ed", size = 3372538 }, - { url = "https://files.pythonhosted.org/packages/0d/74/1009b663387c025e8fa5f3ee3cf3cd0d99b1ad5c72eeb70e75366b1ce878/h5py-3.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7b3b8f3b48717e46c6a790e3128d39c61ab595ae0a7237f06dfad6a3b51d5351", size = 2868104 }, - { url = "https://files.pythonhosted.org/packages/af/52/c604adc06280c15a29037d4aa79a24fe54d8d0b51085e81ed24b2fa995f7/h5py-3.12.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:050a4f2c9126054515169c49cb900949814987f0c7ae74c341b0c9f9b5056834", size = 5194606 }, - { url = "https://files.pythonhosted.org/packages/fa/63/eeaacff417b393491beebabb8a3dc5342950409eb6d7b39d437289abdbae/h5py-3.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c4b41d1019322a5afc5082864dfd6359f8935ecd37c11ac0029be78c5d112c9", size = 5413256 }, - { url = "https://files.pythonhosted.org/packages/86/f7/bb465dcb92ca3521a15cbe1031f6d18234dbf1fb52a6796a00bfaa846ebf/h5py-3.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:e4d51919110a030913201422fb07987db4338eba5ec8c5a15d6fab8e03d443fc", size = 2993055 }, + { url = "https://files.pythonhosted.org/packages/61/1b/ad24a8ce846cf0519695c10491e99969d9d203b9632c4fcd5004b1641c2e/h5py-3.14.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f30dbc58f2a0efeec6c8836c97f6c94afd769023f44e2bb0ed7b17a16ec46088", size = 3352382, upload-time = "2025-06-06T14:04:37.95Z" }, + { url = "https://files.pythonhosted.org/packages/36/5b/a066e459ca48b47cc73a5c668e9924d9619da9e3c500d9fb9c29c03858ec/h5py-3.14.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:543877d7f3d8f8a9828ed5df6a0b78ca3d8846244b9702e99ed0d53610b583a8", size = 2852492, upload-time = "2025-06-06T14:04:42.092Z" }, + { url = "https://files.pythonhosted.org/packages/08/0c/5e6aaf221557314bc15ba0e0da92e40b24af97ab162076c8ae009320a42b/h5py-3.14.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c497600c0496548810047257e36360ff551df8b59156d3a4181072eed47d8ad", size = 4298002, upload-time = "2025-06-06T14:04:47.106Z" }, + { url = "https://files.pythonhosted.org/packages/21/d4/d461649cafd5137088fb7f8e78fdc6621bb0c4ff2c090a389f68e8edc136/h5py-3.14.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:723a40ee6505bd354bfd26385f2dae7bbfa87655f4e61bab175a49d72ebfc06b", size = 4516618, upload-time = "2025-06-06T14:04:52.467Z" }, + { url = "https://files.pythonhosted.org/packages/db/0c/6c3f879a0f8e891625817637fad902da6e764e36919ed091dc77529004ac/h5py-3.14.0-cp311-cp311-win_amd64.whl", hash = "sha256:d2744b520440a996f2dae97f901caa8a953afc055db4673a993f2d87d7f38713", size = 2874888, upload-time = "2025-06-06T14:04:56.95Z" }, + { url = "https://files.pythonhosted.org/packages/3e/77/8f651053c1843391e38a189ccf50df7e261ef8cd8bfd8baba0cbe694f7c3/h5py-3.14.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e0045115d83272090b0717c555a31398c2c089b87d212ceba800d3dc5d952e23", size = 3312740, upload-time = "2025-06-06T14:05:01.193Z" }, + { url = "https://files.pythonhosted.org/packages/ff/10/20436a6cf419b31124e59fefc78d74cb061ccb22213226a583928a65d715/h5py-3.14.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6da62509b7e1d71a7d110478aa25d245dd32c8d9a1daee9d2a42dba8717b047a", size = 2829207, upload-time = "2025-06-06T14:05:05.061Z" }, + { url = "https://files.pythonhosted.org/packages/3f/19/c8bfe8543bfdd7ccfafd46d8cfd96fce53d6c33e9c7921f375530ee1d39a/h5py-3.14.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:554ef0ced3571366d4d383427c00c966c360e178b5fb5ee5bb31a435c424db0c", size = 4708455, upload-time = "2025-06-06T14:05:11.528Z" }, + { url = "https://files.pythonhosted.org/packages/86/f9/f00de11c82c88bfc1ef22633557bfba9e271e0cb3189ad704183fc4a2644/h5py-3.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0cbd41f4e3761f150aa5b662df991868ca533872c95467216f2bec5fcad84882", size = 4929422, upload-time = "2025-06-06T14:05:18.399Z" }, + { url = "https://files.pythonhosted.org/packages/7a/6d/6426d5d456f593c94b96fa942a9b3988ce4d65ebaf57d7273e452a7222e8/h5py-3.14.0-cp312-cp312-win_amd64.whl", hash = "sha256:bf4897d67e613ecf5bdfbdab39a1158a64df105827da70ea1d90243d796d367f", size = 2862845, upload-time = "2025-06-06T14:05:23.699Z" }, + { url = "https://files.pythonhosted.org/packages/6c/c2/7efe82d09ca10afd77cd7c286e42342d520c049a8c43650194928bcc635c/h5py-3.14.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:aa4b7bbce683379b7bf80aaba68e17e23396100336a8d500206520052be2f812", size = 3289245, upload-time = "2025-06-06T14:05:28.24Z" }, + { url = "https://files.pythonhosted.org/packages/4f/31/f570fab1239b0d9441024b92b6ad03bb414ffa69101a985e4c83d37608bd/h5py-3.14.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ef9603a501a04fcd0ba28dd8f0995303d26a77a980a1f9474b3417543d4c6174", size = 2807335, upload-time = "2025-06-06T14:05:31.997Z" }, + { url = "https://files.pythonhosted.org/packages/0d/ce/3a21d87896bc7e3e9255e0ad5583ae31ae9e6b4b00e0bcb2a67e2b6acdbc/h5py-3.14.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8cbaf6910fa3983c46172666b0b8da7b7bd90d764399ca983236f2400436eeb", size = 4700675, upload-time = "2025-06-06T14:05:37.38Z" }, + { url = "https://files.pythonhosted.org/packages/e7/ec/86f59025306dcc6deee5fda54d980d077075b8d9889aac80f158bd585f1b/h5py-3.14.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d90e6445ab7c146d7f7981b11895d70bc1dd91278a4f9f9028bc0c95e4a53f13", size = 4921632, upload-time = "2025-06-06T14:05:43.464Z" }, + { url = "https://files.pythonhosted.org/packages/3f/6d/0084ed0b78d4fd3e7530c32491f2884140d9b06365dac8a08de726421d4a/h5py-3.14.0-cp313-cp313-win_amd64.whl", hash = "sha256:ae18e3de237a7a830adb76aaa68ad438d85fe6e19e0d99944a3ce46b772c69b3", size = 2852929, upload-time = "2025-06-06T14:05:47.659Z" }, ] [[package]] name = "hishel" -version = "0.1.1" +version = "0.1.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "httpx" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/10/b9/d7328c8507e45e27784e9c1f440c2b900ae1e60a980480d869b6c0b2553c/hishel-0.1.1.tar.gz", hash = "sha256:1f6421b78cc23fc43c610f651b7848c9b8eee2d29551d64a2ab0d45b319b6559", size = 35615 } +sdist = { url = "https://files.pythonhosted.org/packages/3e/b5/c063cd3eab8154ddd61deb07b50497cf24010727eaeec4d78ed1a6262986/hishel-0.1.3.tar.gz", hash = "sha256:db3e07429cb739dcda851ff9b35b0f3e7589e21b90ee167df54336ac608b6ec3", size = 36649, upload-time = "2025-07-06T14:19:23.528Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/29/a5/bf3553b44a36e1c5d2aa0cd15478e02b466dcaecdc2983b07068999d2675/hishel-0.1.3-py3-none-any.whl", hash = "sha256:bae3ba9970ffc56f90014aea2b3019158fb0a5b0b635a56f414ba6b96651966e", size = 42518, upload-time = "2025-07-06T14:19:22.336Z" }, +] + +[[package]] +name = "hopsy" +version = "1.6.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "arviz" }, + { name = "matplotlib" }, + { name = "numpy" }, + { name = "optlang" }, + { name = "pandas" }, + { name = "polyround" }, + { name = "scikit-learn" }, + { name = "scipy" }, + { name = "tqdm" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a0/51/164517fc870771d17b3dd9d0afef23b128dc22352688069e238916dec309/hopsy-1.6.1.tar.gz", hash = "sha256:1eb812a0ad42c34ef4c4e949ad804b4860f18795c9447954e175bcbd4b1edf64", size = 7258188, upload-time = "2025-03-30T22:00:24.918Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/e9/93174034316943513a372e1b92d9ee2394973a63d2a99d6ca6432511eca3/hishel-0.1.1-py3-none-any.whl", hash = "sha256:5b51acc340303faeef2f5cfc1658acb1db1fdc3e3ad76406265a485f9707c5d6", size = 41852 }, + { url = "https://files.pythonhosted.org/packages/7f/9e/5a8ff4b789477fe38d745a737505a181015366e1bed39d4fae037cd4daf3/hopsy-1.6.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:0ab345af6d585111a45905357f06ada13dc30a70599a23925b896cec9ed9048a", size = 729960, upload-time = "2025-03-30T21:59:44.756Z" }, + { url = "https://files.pythonhosted.org/packages/be/4b/1ff628b101104c61d600e8701a20a593721f810a517ac5b95de6a79b95c8/hopsy-1.6.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b8fc6257a71ebd06d1a967cae41151d2b31fe490bd3e8c246db14ae7549820a", size = 989378, upload-time = "2025-03-30T21:59:49.087Z" }, + { url = "https://files.pythonhosted.org/packages/04/2b/8f2cf2cc1cb4891c8ddaa5dbb7420809bf0674b82b3bc63fcf1f662880af/hopsy-1.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:20dfc5020a18fde834c38661edb8ea3f1b9c4245f282d79619afe798e0620336", size = 944853, upload-time = "2025-03-30T21:59:52.518Z" }, + { url = "https://files.pythonhosted.org/packages/e5/86/f94eb3f6a5f88e37e53ab45be32240a569ade754d7051003448bc4278e99/hopsy-1.6.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:84d6efa0202dcd7aab716fe240525f32482e90f1d7b8eea07b29d25254b4fc2e", size = 736022, upload-time = "2025-03-30T21:59:55.335Z" }, + { url = "https://files.pythonhosted.org/packages/c2/ae/51077c9eb7aeb51e2f3d6e16fea6930931ad55e73692d19c1da83870f30e/hopsy-1.6.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42843d9fc38d99df1861bc0965a87ecc57c52b11cf4dd1d224b4c9bc8f095eba", size = 992344, upload-time = "2025-03-30T21:59:58.038Z" }, + { url = "https://files.pythonhosted.org/packages/51/f8/612cfaaa6943e27257a22baeb5351c30dc96f0cc8c717457866ef377aba6/hopsy-1.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:efed7a7ec3e58e40055eb70d4694a59ca117ee04930528a8b95824d2f02371f3", size = 961936, upload-time = "2025-03-30T22:00:01.718Z" }, + { url = "https://files.pythonhosted.org/packages/fe/cd/b99bee05141201d7a280b2da0902f59dfda0ba7c96bb34fd53ed7ef3f955/hopsy-1.6.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:2675e0dba93591d5ff144b5d573d1867f09eac71e6c596f59d09390ab068b587", size = 736084, upload-time = "2025-03-30T22:00:04.393Z" }, + { url = "https://files.pythonhosted.org/packages/ca/21/537996d2328368323f08ac9d02fa2e158df63acc210bf19a2dd7ffa28bb5/hopsy-1.6.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdfb78fc445f0f70a2d7025ac42e02de34d2eac457892fd2cdd1f91826fdcece", size = 991801, upload-time = "2025-03-30T22:00:06.882Z" }, + { url = "https://files.pythonhosted.org/packages/1e/37/751ab1e34c8e900737e9d964f63a4dd7e1502684c98c7ef8b1875d24703e/hopsy-1.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:53d49094e96edd7e6b425c62006eae9aeb878fb41ae63cedc54639f685a62f69", size = 961795, upload-time = "2025-03-30T22:00:09.85Z" }, ] [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.9" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, { name = "h11" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b6/44/ed0fa6a17845fb033bd885c03e842f08c1b9406c86a2e60ac1ae1b9206a6/httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f", size = 85180 } +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/06/89/b161908e2f51be56568184aeb4a880fd287178d176fd1c860d2217f41106/httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f", size = 78011 }, + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, ] [[package]] @@ -864,64 +1047,84 @@ dependencies = [ { name = "httpcore" }, { name = "idna" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 } +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 }, + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, ] [[package]] name = "hypothesis" -version = "6.122.1" +version = "6.138.13" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "attrs" }, - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, { name = "sortedcontainers" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/14/f8/df54aa8eed240c09a859ea2d8fca18f011f8cec61d5cf831485e6b20e456/hypothesis-6.122.1.tar.gz", hash = "sha256:23280e802eef88316b02cb32205d74b5bf2e3de4a378e2579a8974117c512b83", size = 413630 } +sdist = { url = "https://files.pythonhosted.org/packages/37/42/9cd666af7fd2c3e604f055f756e80d537faba5327cc72cbd44177792d074/hypothesis-6.138.13.tar.gz", hash = "sha256:2bea91629b8b3bb103a5b51442b1037cede3aae26e56ec063c52b9d5d8eaf70b", size = 466041, upload-time = "2025-09-01T14:02:51.468Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/28/93/aec17891c56dbf038da6ed4f8b3bcfd4f0cc706ac4af0084a7eefad9080d/hypothesis-6.122.1-py3-none-any.whl", hash = "sha256:59e52da0f2529b40f0b7bd0c3c61d8b3fe3337102800bf3534c53d4a8bdf8a6d", size = 474926 }, + { url = "https://files.pythonhosted.org/packages/cc/82/823c202c8b349ff31a0718e46ff98074bebfb3aa20813091cea07821c25f/hypothesis-6.138.13-py3-none-any.whl", hash = "sha256:09f1130deb08e5d12fb3b59b55c113fd79debaaab9b224ffac17be8341de4326", size = 533564, upload-time = "2025-09-01T14:02:48.15Z" }, +] + +[[package]] +name = "identify" +version = "2.6.13" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/82/ca/ffbabe3635bb839aa36b3a893c91a9b0d368cb4d8073e03a12896970af82/identify-2.6.13.tar.gz", hash = "sha256:da8d6c828e773620e13bfa86ea601c5a5310ba4bcd65edf378198b56a1f9fb32", size = 99243, upload-time = "2025-08-09T19:35:00.6Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/ce/461b60a3ee109518c055953729bf9ed089a04db895d47e95444071dcdef2/identify-2.6.13-py2.py3-none-any.whl", hash = "sha256:60381139b3ae39447482ecc406944190f690d4a2997f2584062089848361b33b", size = 99153, upload-time = "2025-08-09T19:34:59.1Z" }, ] [[package]] name = "idna" version = "3.10" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, +] + +[[package]] +name = "importlib-metadata" +version = "8.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "zipp" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/76/66/650a33bd90f786193e4de4b3ad86ea60b53c89b669a5c7be931fac31cdb0/importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000", size = 56641, upload-time = "2025-04-27T15:29:01.736Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, + { url = "https://files.pythonhosted.org/packages/20/b0/36bd937216ec521246249be3bf9855081de4c5e06a0c9b4219dbeda50373/importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd", size = 27656, upload-time = "2025-04-27T15:29:00.214Z" }, ] [[package]] name = "importlib-resources" -version = "6.4.5" +version = "6.5.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/98/be/f3e8c6081b684f176b761e6a2fef02a0be939740ed6f54109a2951d806f3/importlib_resources-6.4.5.tar.gz", hash = "sha256:980862a1d16c9e147a59603677fa2aa5fd82b87f223b6cb870695bcfce830065", size = 43372 } +sdist = { url = "https://files.pythonhosted.org/packages/cf/8c/f834fbf984f691b4f7ff60f50b514cc3de5cc08abfc3295564dd89c5e2e7/importlib_resources-6.5.2.tar.gz", hash = "sha256:185f87adef5bcc288449d98fb4fba07cea78bc036455dd44c5fc4a2fe78fed2c", size = 44693, upload-time = "2025-01-03T18:51:56.698Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e1/6a/4604f9ae2fa62ef47b9de2fa5ad599589d28c9fd1d335f32759813dfa91e/importlib_resources-6.4.5-py3-none-any.whl", hash = "sha256:ac29d5f956f01d5e4bb63102a5a19957f1b9175e45649977264a1416783bb717", size = 36115 }, + { url = "https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl", hash = "sha256:789cfdc3ed28c78b67a06acb8126751ced69a3d5f79c095a98298cd8a760ccec", size = 37461, upload-time = "2025-01-03T18:51:54.306Z" }, ] [[package]] name = "indexed" version = "1.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/07/91/ebbff25d520fd4c904fcec67a1e4800c6e37c17f4c64057693e38aa2455b/indexed-1.3.0.tar.gz", hash = "sha256:6a0dd1f164db2eef6f9983bf1c5302d4b250a05b784f15c4c3f436d8778243d9", size = 5458 } +sdist = { url = "https://files.pythonhosted.org/packages/07/91/ebbff25d520fd4c904fcec67a1e4800c6e37c17f4c64057693e38aa2455b/indexed-1.3.0.tar.gz", hash = "sha256:6a0dd1f164db2eef6f9983bf1c5302d4b250a05b784f15c4c3f436d8778243d9", size = 5458, upload-time = "2022-10-26T20:53:09.176Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/62/8b/e5c5af4bb7f87409afd3addd3612bc471b2e141987d3edf64c7693cae7c4/indexed-1.3.0-py3-none-any.whl", hash = "sha256:a35db8644bef9273be710f5f06b5ffe71b8699d9212593cbae422b5e3c5f64c6", size = 5619 }, + { url = "https://files.pythonhosted.org/packages/62/8b/e5c5af4bb7f87409afd3addd3612bc471b2e141987d3edf64c7693cae7c4/indexed-1.3.0-py3-none-any.whl", hash = "sha256:a35db8644bef9273be710f5f06b5ffe71b8699d9212593cbae422b5e3c5f64c6", size = 5619, upload-time = "2022-10-26T20:53:06.536Z" }, ] [[package]] name = "iniconfig" -version = "2.0.0" +version = "2.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 } +sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, + { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, ] [[package]] name = "ipykernel" -version = "6.29.5" +version = "6.30.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "appnope", marker = "sys_platform == 'darwin'" }, @@ -938,30 +1141,43 @@ dependencies = [ { name = "tornado" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e9/5c/67594cb0c7055dc50814b21731c22a601101ea3b1b50a9a1b090e11f5d0f/ipykernel-6.29.5.tar.gz", hash = "sha256:f093a22c4a40f8828f8e330a9c297cb93dcab13bd9678ded6de8e5cf81c56215", size = 163367 } +sdist = { url = "https://files.pythonhosted.org/packages/bb/76/11082e338e0daadc89c8ff866185de11daf67d181901038f9e139d109761/ipykernel-6.30.1.tar.gz", hash = "sha256:6abb270161896402e76b91394fcdce5d1be5d45f456671e5080572f8505be39b", size = 166260, upload-time = "2025-08-04T15:47:35.018Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/94/5c/368ae6c01c7628438358e6d337c19b05425727fbb221d2a3c4303c372f42/ipykernel-6.29.5-py3-none-any.whl", hash = "sha256:afdb66ba5aa354b09b91379bac28ae4afebbb30e8b39510c9690afb7a10421b5", size = 117173 }, + { url = "https://files.pythonhosted.org/packages/fc/c7/b445faca8deb954fe536abebff4ece5b097b923de482b26e78448c89d1dd/ipykernel-6.30.1-py3-none-any.whl", hash = "sha256:aa6b9fb93dca949069d8b85b6c79b2518e32ac583ae9c7d37c51d119e18b3fb4", size = 117484, upload-time = "2025-08-04T15:47:32.622Z" }, ] [[package]] name = "ipython" -version = "8.18.0" +version = "9.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, { name = "decorator" }, - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "ipython-pygments-lexers" }, { name = "jedi" }, { name = "matplotlib-inline" }, - { name = "pexpect", marker = "sys_platform != 'win32'" }, + { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" }, { name = "prompt-toolkit" }, { name = "pygments" }, { name = "stack-data" }, { name = "traitlets" }, + { name = "typing-extensions", marker = "python_full_version < '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6e/71/a86262bf5a68bf211bcc71fe302af7e05f18a2852fdc610a854d20d085e6/ipython-9.5.0.tar.gz", hash = "sha256:129c44b941fe6d9b82d36fc7a7c18127ddb1d6f02f78f867f402e2e3adde3113", size = 4389137, upload-time = "2025-08-29T12:15:21.519Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/08/2a/5628a99d04acb2d2f2e749cdf4ea571d2575e898df0528a090948018b726/ipython-9.5.0-py3-none-any.whl", hash = "sha256:88369ffa1d5817d609120daa523a6da06d02518e582347c29f8451732a9c5e72", size = 612426, upload-time = "2025-08-29T12:15:18.866Z" }, +] + +[[package]] +name = "ipython-pygments-lexers" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9b/af/e1ff4d5499165e330413e0fb9811ca937c332d20900eae641cd590c0ab71/ipython-8.18.0.tar.gz", hash = "sha256:4feb61210160f75e229ce932dbf8b719bff37af123c0b985fd038b14233daa16", size = 5486388 } +sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393, upload-time = "2025-01-17T11:24:34.505Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7a/57/ef12725f8af19920db1d8f2eaee44ebbaee6d9fdcf853be5db76bfdb9ce6/ipython-8.18.0-py3-none-any.whl", hash = "sha256:d538a7a98ad9b7e018926447a5f35856113a85d08fd68a165d7871ab5175f6e0", size = 808166 }, + { url = "https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c", size = 8074, upload-time = "2025-01-17T11:24:33.271Z" }, ] [[package]] @@ -971,9 +1187,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "arrow" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7c/1a/3c8edc664e06e6bd06cce40c6b22da5f1429aa4224d0c590f3be21c91ead/isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9", size = 11649 } +sdist = { url = "https://files.pythonhosted.org/packages/7c/1a/3c8edc664e06e6bd06cce40c6b22da5f1429aa4224d0c590f3be21c91ead/isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9", size = 11649, upload-time = "2020-11-01T11:00:00.312Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042", size = 11321 }, + { url = "https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042", size = 11321, upload-time = "2020-11-01T10:59:58.02Z" }, ] [[package]] @@ -983,53 +1199,53 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "parso" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/72/3a/79a912fbd4d8dd6fbb02bf69afd3bb72cf0c729bb3063c6f4498603db17a/jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0", size = 1231287 } +sdist = { url = "https://files.pythonhosted.org/packages/72/3a/79a912fbd4d8dd6fbb02bf69afd3bb72cf0c729bb3063c6f4498603db17a/jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0", size = 1231287, upload-time = "2024-11-11T01:41:42.873Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278 }, + { url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278, upload-time = "2024-11-11T01:41:40.175Z" }, ] [[package]] name = "jinja2" -version = "3.1.4" +version = "3.1.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ed/55/39036716d19cab0747a5020fc7e907f362fbf48c984b14e62127f7e68e5d/jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", size = 240245 } +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/80/3a54838c3fb461f6fec263ebf3a3a41771bd05190238de3486aae8540c36/jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d", size = 133271 }, + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, ] [[package]] name = "joblib" -version = "1.4.2" +version = "1.5.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/64/33/60135848598c076ce4b231e1b1895170f45fbcaeaa2c9d5e38b04db70c35/joblib-1.4.2.tar.gz", hash = "sha256:2382c5816b2636fbd20a09e0f4e9dad4736765fdfb7dca582943b9c1366b3f0e", size = 2116621 } +sdist = { url = "https://files.pythonhosted.org/packages/e8/5d/447af5ea094b9e4c4054f82e223ada074c552335b9b4b2d14bd9b35a67c4/joblib-1.5.2.tar.gz", hash = "sha256:3faa5c39054b2f03ca547da9b2f52fde67c06240c31853f306aea97f13647b55", size = 331077, upload-time = "2025-08-27T12:15:46.575Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/91/29/df4b9b42f2be0b623cbd5e2140cafcaa2bef0759a00b7b70104dcfe2fb51/joblib-1.4.2-py3-none-any.whl", hash = "sha256:06d478d5674cbc267e7496a410ee875abd68e4340feff4490bcb7afb88060ae6", size = 301817 }, + { url = "https://files.pythonhosted.org/packages/1e/e8/685f47e0d754320684db4425a0967f7d3fa70126bffd76110b7009a0090f/joblib-1.5.2-py3-none-any.whl", hash = "sha256:4e1f0bdbb987e6d843c70cf43714cb276623def372df3c22fe5266b2670bc241", size = 308396, upload-time = "2025-08-27T12:15:45.188Z" }, ] [[package]] name = "json5" -version = "0.10.0" +version = "0.12.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/85/3d/bbe62f3d0c05a689c711cff57b2e3ac3d3e526380adb7c781989f075115c/json5-0.10.0.tar.gz", hash = "sha256:e66941c8f0a02026943c52c2eb34ebeb2a6f819a0be05920a6f5243cd30fd559", size = 48202 } +sdist = { url = "https://files.pythonhosted.org/packages/12/ae/929aee9619e9eba9015207a9d2c1c54db18311da7eb4dcf6d41ad6f0eb67/json5-0.12.1.tar.gz", hash = "sha256:b2743e77b3242f8d03c143dd975a6ec7c52e2f2afe76ed934e53503dd4ad4990", size = 52191, upload-time = "2025-08-12T19:47:42.583Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/aa/42/797895b952b682c3dafe23b1834507ee7f02f4d6299b65aaa61425763278/json5-0.10.0-py3-none-any.whl", hash = "sha256:19b23410220a7271e8377f81ba8aacba2fdd56947fbb137ee5977cbe1f5e8dfa", size = 34049 }, + { url = "https://files.pythonhosted.org/packages/85/e2/05328bd2621be49a6fed9e3030b1e51a2d04537d3f816d211b9cc53c5262/json5-0.12.1-py3-none-any.whl", hash = "sha256:d9c9b3bc34a5f54d43c35e11ef7cb87d8bdd098c6ace87117a7b7e83e705c1d5", size = 36119, upload-time = "2025-08-12T19:47:41.131Z" }, ] [[package]] name = "jsonpointer" version = "3.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6a/0a/eebeb1fa92507ea94016a2a790b93c2ae41a7e18778f85471dc54475ed25/jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef", size = 9114 } +sdist = { url = "https://files.pythonhosted.org/packages/6a/0a/eebeb1fa92507ea94016a2a790b93c2ae41a7e18778f85471dc54475ed25/jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef", size = 9114, upload-time = "2024-06-10T19:24:42.462Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942", size = 7595 }, + { url = "https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942", size = 7595, upload-time = "2024-06-10T19:24:40.698Z" }, ] [[package]] name = "jsonschema" -version = "4.23.0" +version = "4.25.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "attrs" }, @@ -1037,9 +1253,9 @@ dependencies = [ { name = "referencing" }, { name = "rpds-py" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/38/2e/03362ee4034a4c917f697890ccd4aec0800ccf9ded7f511971c75451deec/jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4", size = 325778 } +sdist = { url = "https://files.pythonhosted.org/packages/74/69/f7185de793a29082a9f3c7728268ffb31cb5095131a9c139a74078e27336/jsonschema-4.25.1.tar.gz", hash = "sha256:e4a9655ce0da0c0b67a085847e00a3a51449e1157f4f75e9fb5aa545e122eb85", size = 357342, upload-time = "2025-08-18T17:03:50.038Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/69/4a/4f9dbeb84e8850557c02365a0eee0649abe5eb1d84af92a25731c6c0f922/jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566", size = 88462 }, + { url = "https://files.pythonhosted.org/packages/bf/9c/8c95d856233c1f82500c2450b8c68576b4cf1c871db3afac5c34ff84e6fd/jsonschema-4.25.1-py3-none-any.whl", hash = "sha256:3fba0169e345c7175110351d456342c364814cfcf3b964ba4587f22915230a63", size = 90040, upload-time = "2025-08-18T17:03:48.373Z" }, ] [package.optional-dependencies] @@ -1050,20 +1266,21 @@ format-nongpl = [ { name = "jsonpointer" }, { name = "rfc3339-validator" }, { name = "rfc3986-validator" }, + { name = "rfc3987-syntax" }, { name = "uri-template" }, { name = "webcolors" }, ] [[package]] name = "jsonschema-specifications" -version = "2024.10.1" +version = "2025.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "referencing" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/10/db/58f950c996c793472e336ff3655b13fbcf1e3b359dcf52dcf3ed3b52c352/jsonschema_specifications-2024.10.1.tar.gz", hash = "sha256:0f38b83639958ce1152d02a7f062902c41c8fd20d558b0c34344292d417ae272", size = 15561 } +sdist = { url = "https://files.pythonhosted.org/packages/bf/ce/46fbd9c8119cfc3581ee5643ea49464d168028cfb5caff5fc0596d0cf914/jsonschema_specifications-2025.4.1.tar.gz", hash = "sha256:630159c9f4dbea161a6a2205c3011cc4f18ff381b189fff48bb39b9bf26ae608", size = 15513, upload-time = "2025-04-23T12:34:07.418Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/0f/8910b19ac0670a0f80ce1008e5e751c4a57e14d2c4c13a482aa6079fa9d6/jsonschema_specifications-2024.10.1-py3-none-any.whl", hash = "sha256:a09a0680616357d9a0ecf05c12ad234479f549239d0f5b55f3deea67475da9bf", size = 18459 }, + { url = "https://files.pythonhosted.org/packages/01/0e/b27cdbaccf30b890c40ed1da9fd4a3593a5cf94dae54fb34f8a4b74fcd3f/jsonschema_specifications-2025.4.1-py3-none-any.whl", hash = "sha256:4653bffbd6584f7de83a67e0d620ef16900b390ddc7939d56684d6c81e33f1af", size = 18437, upload-time = "2025-04-23T12:34:05.422Z" }, ] [[package]] @@ -1077,31 +1294,32 @@ dependencies = [ { name = "tornado" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/71/22/bf9f12fdaeae18019a468b68952a60fe6dbab5d67cd2a103cac7659b41ca/jupyter_client-8.6.3.tar.gz", hash = "sha256:35b3a0947c4a6e9d589eb97d7d4cd5e90f910ee73101611f01283732bd6d9419", size = 342019 } +sdist = { url = "https://files.pythonhosted.org/packages/71/22/bf9f12fdaeae18019a468b68952a60fe6dbab5d67cd2a103cac7659b41ca/jupyter_client-8.6.3.tar.gz", hash = "sha256:35b3a0947c4a6e9d589eb97d7d4cd5e90f910ee73101611f01283732bd6d9419", size = 342019, upload-time = "2024-09-17T10:44:17.613Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/11/85/b0394e0b6fcccd2c1eeefc230978a6f8cb0c5df1e4cd3e7625735a0d7d1e/jupyter_client-8.6.3-py3-none-any.whl", hash = "sha256:e8a19cc986cc45905ac3362915f410f3af85424b4c0905e94fa5f2cb08e8f23f", size = 106105 }, + { url = "https://files.pythonhosted.org/packages/11/85/b0394e0b6fcccd2c1eeefc230978a6f8cb0c5df1e4cd3e7625735a0d7d1e/jupyter_client-8.6.3-py3-none-any.whl", hash = "sha256:e8a19cc986cc45905ac3362915f410f3af85424b4c0905e94fa5f2cb08e8f23f", size = 106105, upload-time = "2024-09-17T10:44:15.218Z" }, ] [[package]] name = "jupyter-core" -version = "5.7.2" +version = "5.8.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "platformdirs" }, { name = "pywin32", marker = "platform_python_implementation != 'PyPy' and sys_platform == 'win32'" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/00/11/b56381fa6c3f4cc5d2cf54a7dbf98ad9aa0b339ef7a601d6053538b079a7/jupyter_core-5.7.2.tar.gz", hash = "sha256:aa5f8d32bbf6b431ac830496da7392035d6f61b4f54872f15c4bd2a9c3f536d9", size = 87629 } +sdist = { url = "https://files.pythonhosted.org/packages/99/1b/72906d554acfeb588332eaaa6f61577705e9ec752ddb486f302dafa292d9/jupyter_core-5.8.1.tar.gz", hash = "sha256:0a5f9706f70e64786b75acba995988915ebd4601c8a52e534a40b51c95f59941", size = 88923, upload-time = "2025-05-27T07:38:16.655Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c9/fb/108ecd1fe961941959ad0ee4e12ee7b8b1477247f30b1fdfd83ceaf017f0/jupyter_core-5.7.2-py3-none-any.whl", hash = "sha256:4f7315d2f6b4bcf2e3e7cb6e46772eba760ae459cd1f59d29eb57b0a01bd7409", size = 28965 }, + { url = "https://files.pythonhosted.org/packages/2f/57/6bffd4b20b88da3800c5d691e0337761576ee688eb01299eae865689d2df/jupyter_core-5.8.1-py3-none-any.whl", hash = "sha256:c28d268fc90fb53f1338ded2eb410704c5449a358406e8a948b75706e24863d0", size = 28880, upload-time = "2025-05-27T07:38:15.137Z" }, ] [[package]] name = "jupyter-events" -version = "0.10.0" +version = "0.12.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jsonschema", extra = ["format-nongpl"] }, + { name = "packaging" }, { name = "python-json-logger" }, { name = "pyyaml" }, { name = "referencing" }, @@ -1109,26 +1327,26 @@ dependencies = [ { name = "rfc3986-validator" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8d/53/7537a1aa558229bb0b1b178d814c9d68a9c697d3aecb808a1cb2646acf1f/jupyter_events-0.10.0.tar.gz", hash = "sha256:670b8229d3cc882ec782144ed22e0d29e1c2d639263f92ca8383e66682845e22", size = 61516 } +sdist = { url = "https://files.pythonhosted.org/packages/9d/c3/306d090461e4cf3cd91eceaff84bede12a8e52cd821c2d20c9a4fd728385/jupyter_events-0.12.0.tar.gz", hash = "sha256:fc3fce98865f6784c9cd0a56a20644fc6098f21c8c33834a8d9fe383c17e554b", size = 62196, upload-time = "2025-02-03T17:23:41.485Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a5/94/059180ea70a9a326e1815176b2370da56376da347a796f8c4f0b830208ef/jupyter_events-0.10.0-py3-none-any.whl", hash = "sha256:4b72130875e59d57716d327ea70d3ebc3af1944d3717e5a498b8a06c6c159960", size = 18777 }, + { url = "https://files.pythonhosted.org/packages/e2/48/577993f1f99c552f18a0428731a755e06171f9902fa118c379eb7c04ea22/jupyter_events-0.12.0-py3-none-any.whl", hash = "sha256:6464b2fa5ad10451c3d35fabc75eab39556ae1e2853ad0c0cc31b656731a97fb", size = 19430, upload-time = "2025-02-03T17:23:38.643Z" }, ] [[package]] name = "jupyter-lsp" -version = "2.2.5" +version = "2.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jupyter-server" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/85/b4/3200b0b09c12bc3b72d943d923323c398eff382d1dcc7c0dbc8b74630e40/jupyter-lsp-2.2.5.tar.gz", hash = "sha256:793147a05ad446f809fd53ef1cd19a9f5256fd0a2d6b7ce943a982cb4f545001", size = 48741 } +sdist = { url = "https://files.pythonhosted.org/packages/eb/5a/9066c9f8e94ee517133cd98dba393459a16cd48bba71a82f16a65415206c/jupyter_lsp-2.3.0.tar.gz", hash = "sha256:458aa59339dc868fb784d73364f17dbce8836e906cd75fd471a325cba02e0245", size = 54823, upload-time = "2025-08-27T17:47:34.671Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/07/e0/7bd7cff65594fd9936e2f9385701e44574fc7d721331ff676ce440b14100/jupyter_lsp-2.2.5-py3-none-any.whl", hash = "sha256:45fbddbd505f3fbfb0b6cb2f1bc5e15e83ab7c79cd6e89416b248cb3c00c11da", size = 69146 }, + { url = "https://files.pythonhosted.org/packages/1a/60/1f6cee0c46263de1173894f0fafcb3475ded276c472c14d25e0280c18d6d/jupyter_lsp-2.3.0-py3-none-any.whl", hash = "sha256:e914a3cb2addf48b1c7710914771aaf1819d46b2e5a79b0f917b5478ec93f34f", size = 76687, upload-time = "2025-08-27T17:47:33.15Z" }, ] [[package]] name = "jupyter-server" -version = "2.14.2" +version = "2.17.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -1140,7 +1358,7 @@ dependencies = [ { name = "jupyter-server-terminals" }, { name = "nbconvert" }, { name = "nbformat" }, - { name = "overrides" }, + { name = "overrides", marker = "python_full_version < '3.12'" }, { name = "packaging" }, { name = "prometheus-client" }, { name = "pywinpty", marker = "os_name == 'nt'" }, @@ -1151,9 +1369,9 @@ dependencies = [ { name = "traitlets" }, { name = "websocket-client" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0c/34/88b47749c7fa9358e10eac356c4b97d94a91a67d5c935a73f69bc4a31118/jupyter_server-2.14.2.tar.gz", hash = "sha256:66095021aa9638ced276c248b1d81862e4c50f292d575920bbe960de1c56b12b", size = 719933 } +sdist = { url = "https://files.pythonhosted.org/packages/5b/ac/e040ec363d7b6b1f11304cc9f209dac4517ece5d5e01821366b924a64a50/jupyter_server-2.17.0.tar.gz", hash = "sha256:c38ea898566964c888b4772ae1ed58eca84592e88251d2cfc4d171f81f7e99d5", size = 731949, upload-time = "2025-08-21T14:42:54.042Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/57/e1/085edea6187a127ca8ea053eb01f4e1792d778b4d192c74d32eb6730fed6/jupyter_server-2.14.2-py3-none-any.whl", hash = "sha256:47ff506127c2f7851a17bf4713434208fc490955d0e8632e95014a9a9afbeefd", size = 383556 }, + { url = "https://files.pythonhosted.org/packages/92/80/a24767e6ca280f5a49525d987bf3e4d7552bf67c8be07e8ccf20271f8568/jupyter_server-2.17.0-py3-none-any.whl", hash = "sha256:e8cb9c7db4251f51ed307e329b81b72ccf2056ff82d50524debde1ee1870e13f", size = 388221, upload-time = "2025-08-21T14:42:52.034Z" }, ] [[package]] @@ -1164,14 +1382,14 @@ dependencies = [ { name = "pywinpty", marker = "os_name == 'nt'" }, { name = "terminado" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fc/d5/562469734f476159e99a55426d697cbf8e7eb5efe89fb0e0b4f83a3d3459/jupyter_server_terminals-0.5.3.tar.gz", hash = "sha256:5ae0295167220e9ace0edcfdb212afd2b01ee8d179fe6f23c899590e9b8a5269", size = 31430 } +sdist = { url = "https://files.pythonhosted.org/packages/fc/d5/562469734f476159e99a55426d697cbf8e7eb5efe89fb0e0b4f83a3d3459/jupyter_server_terminals-0.5.3.tar.gz", hash = "sha256:5ae0295167220e9ace0edcfdb212afd2b01ee8d179fe6f23c899590e9b8a5269", size = 31430, upload-time = "2024-03-12T14:37:03.049Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/07/2d/2b32cdbe8d2a602f697a649798554e4f072115438e92249624e532e8aca6/jupyter_server_terminals-0.5.3-py3-none-any.whl", hash = "sha256:41ee0d7dc0ebf2809c668e0fc726dfaf258fcd3e769568996ca731b6194ae9aa", size = 13656 }, + { url = "https://files.pythonhosted.org/packages/07/2d/2b32cdbe8d2a602f697a649798554e4f072115438e92249624e532e8aca6/jupyter_server_terminals-0.5.3-py3-none-any.whl", hash = "sha256:41ee0d7dc0ebf2809c668e0fc726dfaf258fcd3e769568996ca731b6194ae9aa", size = 13656, upload-time = "2024-03-12T14:37:00.708Z" }, ] [[package]] name = "jupyterlab" -version = "4.3.2" +version = "4.4.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "async-lru" }, @@ -1185,22 +1403,21 @@ dependencies = [ { name = "notebook-shim" }, { name = "packaging" }, { name = "setuptools" }, - { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "tornado" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6b/2b/a3b8005643a5583841e0ec3e5e187330f5d4e5f4be232b2f00a653ab2d3d/jupyterlab-4.3.2.tar.gz", hash = "sha256:3c0a6882dbddcc0a7bfdd5e2236f351b2b263e48780236e6996c2aca13ac5b22", size = 21797175 } +sdist = { url = "https://files.pythonhosted.org/packages/1e/5c/14f0852233d60d30bf0f22a817d6c20ac555d73526cc915274f97c07a2b9/jupyterlab-4.4.6.tar.gz", hash = "sha256:e0b720ff5392846bdbc01745f32f29f4d001c071a4bff94d8b516ba89b5a4157", size = 23040936, upload-time = "2025-08-15T11:44:15.915Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/12/fc/f12dbf6e3f44d8f95645c9142e40e7e7de1e7af284b286f35acf88df5b87/jupyterlab-4.3.2-py3-none-any.whl", hash = "sha256:e87100cbab8b886ff7a4f325c856100ba6fdfe916162a85409daf0e707e19d1d", size = 11664945 }, + { url = "https://files.pythonhosted.org/packages/53/38/6182d63f39428821e705e86fba61704fc69769a24ca5a9578c2c04986c9a/jupyterlab-4.4.6-py3-none-any.whl", hash = "sha256:e877e930f46dde2e3ee9da36a935c6cd4fdb15aa7440519d0fde696f9fadb833", size = 12268564, upload-time = "2025-08-15T11:44:11.42Z" }, ] [[package]] name = "jupyterlab-pygments" version = "0.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/90/51/9187be60d989df97f5f0aba133fa54e7300f17616e065d1ada7d7646b6d6/jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d", size = 512900 } +sdist = { url = "https://files.pythonhosted.org/packages/90/51/9187be60d989df97f5f0aba133fa54e7300f17616e065d1ada7d7646b6d6/jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d", size = 512900, upload-time = "2023-11-23T09:26:37.44Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780", size = 15884 }, + { url = "https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780", size = 15884, upload-time = "2023-11-23T09:26:34.325Z" }, ] [[package]] @@ -1216,184 +1433,216 @@ dependencies = [ { name = "packaging" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0a/c9/a883ce65eb27905ce77ace410d83587c82ea64dc85a48d1f7ed52bcfa68d/jupyterlab_server-2.27.3.tar.gz", hash = "sha256:eb36caca59e74471988f0ae25c77945610b887f777255aa21f8065def9e51ed4", size = 76173 } +sdist = { url = "https://files.pythonhosted.org/packages/0a/c9/a883ce65eb27905ce77ace410d83587c82ea64dc85a48d1f7ed52bcfa68d/jupyterlab_server-2.27.3.tar.gz", hash = "sha256:eb36caca59e74471988f0ae25c77945610b887f777255aa21f8065def9e51ed4", size = 76173, upload-time = "2024-07-16T17:02:04.149Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/54/09/2032e7d15c544a0e3cd831c51d77a8ca57f7555b2e1b2922142eddb02a84/jupyterlab_server-2.27.3-py3-none-any.whl", hash = "sha256:e697488f66c3db49df675158a77b3b017520d772c6e1548c7d9bcc5df7944ee4", size = 59700 }, + { url = "https://files.pythonhosted.org/packages/54/09/2032e7d15c544a0e3cd831c51d77a8ca57f7555b2e1b2922142eddb02a84/jupyterlab_server-2.27.3-py3-none-any.whl", hash = "sha256:e697488f66c3db49df675158a77b3b017520d772c6e1548c7d9bcc5df7944ee4", size = 59700, upload-time = "2024-07-16T17:02:01.115Z" }, ] [[package]] name = "kaleido" -version = "0.2.1" +version = "1.0.0" source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "choreographer" }, + { name = "logistro" }, + { name = "orjson" }, + { name = "packaging" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/15/dc/fd2d955884f45f852152d44f5ecf79de3cb58da0f995b6f6f9acfc80dd94/kaleido-1.0.0.tar.gz", hash = "sha256:502d8ba64737924efaf5e94c2736745bcc7c926e6cc535838be36c0fc06330bd", size = 49400, upload-time = "2025-06-19T15:50:39.357Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/f7/0ccaa596ec341963adbb4f839774c36d5659e75a0812d946732b927d480e/kaleido-0.2.1-py2.py3-none-macosx_10_11_x86_64.whl", hash = "sha256:ca6f73e7ff00aaebf2843f73f1d3bacde1930ef5041093fe76b83a15785049a7", size = 85153681 }, - { url = "https://files.pythonhosted.org/packages/45/8e/4297556be5a07b713bb42dde0f748354de9a6918dee251c0e6bdcda341e7/kaleido-0.2.1-py2.py3-none-macosx_11_0_arm64.whl", hash = "sha256:bb9a5d1f710357d5d432ee240ef6658a6d124c3e610935817b4b42da9c787c05", size = 85808197 }, - { url = "https://files.pythonhosted.org/packages/ae/b3/a0f0f4faac229b0011d8c4a7ee6da7c2dca0b6fd08039c95920846f23ca4/kaleido-0.2.1-py2.py3-none-manylinux1_x86_64.whl", hash = "sha256:aa21cf1bf1c78f8fa50a9f7d45e1003c387bd3d6fe0a767cfbbf344b95bdc3a8", size = 79902476 }, - { url = "https://files.pythonhosted.org/packages/a1/2b/680662678a57afab1685f0c431c2aba7783ce4344f06ec162074d485d469/kaleido-0.2.1-py2.py3-none-manylinux2014_aarch64.whl", hash = "sha256:845819844c8082c9469d9c17e42621fbf85c2b237ef8a86ec8a8527f98b6512a", size = 83711746 }, - { url = "https://files.pythonhosted.org/packages/88/89/4b6f8bb3f9ab036fd4ad1cb2d628ab5c81db32ac9aa0641d7b180073ba43/kaleido-0.2.1-py2.py3-none-win32.whl", hash = "sha256:ecc72635860be616c6b7161807a65c0dbd9b90c6437ac96965831e2e24066552", size = 62312480 }, - { url = "https://files.pythonhosted.org/packages/f7/9a/0408b02a4bcb3cf8b338a2b074ac7d1b2099e2b092b42473def22f7b625f/kaleido-0.2.1-py2.py3-none-win_amd64.whl", hash = "sha256:4670985f28913c2d063c5734d125ecc28e40810141bdb0a46f15b76c1d45f23c", size = 65945521 }, + { url = "https://files.pythonhosted.org/packages/28/0e/853df00cac4823eaa8f35114d0d0ad1e2ec6b8243ce4acf5f8ac5235c517/kaleido-1.0.0-py3-none-any.whl", hash = "sha256:a7e8bd95648378d2746f6c86084d419d15f95b1ec7bb0ec810289b7feb25b18d", size = 51479, upload-time = "2025-06-19T15:50:37.884Z" }, ] [[package]] name = "kiwisolver" -version = "1.4.7" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/85/4d/2255e1c76304cbd60b48cee302b66d1dde4468dc5b1160e4b7cb43778f2a/kiwisolver-1.4.7.tar.gz", hash = "sha256:9893ff81bd7107f7b685d3017cc6583daadb4fc26e4a888350df530e41980a60", size = 97286 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/97/14/fc943dd65268a96347472b4fbe5dcc2f6f55034516f80576cd0dd3a8930f/kiwisolver-1.4.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8a9c83f75223d5e48b0bc9cb1bf2776cf01563e00ade8775ffe13b0b6e1af3a6", size = 122440 }, - { url = "https://files.pythonhosted.org/packages/1e/46/e68fed66236b69dd02fcdb506218c05ac0e39745d696d22709498896875d/kiwisolver-1.4.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:58370b1ffbd35407444d57057b57da5d6549d2d854fa30249771775c63b5fe17", size = 65758 }, - { url = "https://files.pythonhosted.org/packages/ef/fa/65de49c85838681fc9cb05de2a68067a683717321e01ddafb5b8024286f0/kiwisolver-1.4.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aa0abdf853e09aff551db11fce173e2177d00786c688203f52c87ad7fcd91ef9", size = 64311 }, - { url = "https://files.pythonhosted.org/packages/42/9c/cc8d90f6ef550f65443bad5872ffa68f3dee36de4974768628bea7c14979/kiwisolver-1.4.7-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8d53103597a252fb3ab8b5845af04c7a26d5e7ea8122303dd7a021176a87e8b9", size = 1637109 }, - { url = "https://files.pythonhosted.org/packages/55/91/0a57ce324caf2ff5403edab71c508dd8f648094b18cfbb4c8cc0fde4a6ac/kiwisolver-1.4.7-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:88f17c5ffa8e9462fb79f62746428dd57b46eb931698e42e990ad63103f35e6c", size = 1617814 }, - { url = "https://files.pythonhosted.org/packages/12/5d/c36140313f2510e20207708adf36ae4919416d697ee0236b0ddfb6fd1050/kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88a9ca9c710d598fd75ee5de59d5bda2684d9db36a9f50b6125eaea3969c2599", size = 1400881 }, - { url = "https://files.pythonhosted.org/packages/56/d0/786e524f9ed648324a466ca8df86298780ef2b29c25313d9a4f16992d3cf/kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f4d742cb7af1c28303a51b7a27aaee540e71bb8e24f68c736f6f2ffc82f2bf05", size = 1512972 }, - { url = "https://files.pythonhosted.org/packages/67/5a/77851f2f201e6141d63c10a0708e996a1363efaf9e1609ad0441b343763b/kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e28c7fea2196bf4c2f8d46a0415c77a1c480cc0724722f23d7410ffe9842c407", size = 1444787 }, - { url = "https://files.pythonhosted.org/packages/06/5f/1f5eaab84355885e224a6fc8d73089e8713dc7e91c121f00b9a1c58a2195/kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e968b84db54f9d42046cf154e02911e39c0435c9801681e3fc9ce8a3c4130278", size = 2199212 }, - { url = "https://files.pythonhosted.org/packages/b5/28/9152a3bfe976a0ae21d445415defc9d1cd8614b2910b7614b30b27a47270/kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0c18ec74c0472de033e1bebb2911c3c310eef5649133dd0bedf2a169a1b269e5", size = 2346399 }, - { url = "https://files.pythonhosted.org/packages/26/f6/453d1904c52ac3b400f4d5e240ac5fec25263716723e44be65f4d7149d13/kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8f0ea6da6d393d8b2e187e6a5e3fb81f5862010a40c3945e2c6d12ae45cfb2ad", size = 2308688 }, - { url = "https://files.pythonhosted.org/packages/5a/9a/d4968499441b9ae187e81745e3277a8b4d7c60840a52dc9d535a7909fac3/kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:f106407dda69ae456dd1227966bf445b157ccc80ba0dff3802bb63f30b74e895", size = 2445493 }, - { url = "https://files.pythonhosted.org/packages/07/c9/032267192e7828520dacb64dfdb1d74f292765f179e467c1cba97687f17d/kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:84ec80df401cfee1457063732d90022f93951944b5b58975d34ab56bb150dfb3", size = 2262191 }, - { url = "https://files.pythonhosted.org/packages/6c/ad/db0aedb638a58b2951da46ddaeecf204be8b4f5454df020d850c7fa8dca8/kiwisolver-1.4.7-cp310-cp310-win32.whl", hash = "sha256:71bb308552200fb2c195e35ef05de12f0c878c07fc91c270eb3d6e41698c3bcc", size = 46644 }, - { url = "https://files.pythonhosted.org/packages/12/ca/d0f7b7ffbb0be1e7c2258b53554efec1fd652921f10d7d85045aff93ab61/kiwisolver-1.4.7-cp310-cp310-win_amd64.whl", hash = "sha256:44756f9fd339de0fb6ee4f8c1696cfd19b2422e0d70b4cefc1cc7f1f64045a8c", size = 55877 }, - { url = "https://files.pythonhosted.org/packages/97/6c/cfcc128672f47a3e3c0d918ecb67830600078b025bfc32d858f2e2d5c6a4/kiwisolver-1.4.7-cp310-cp310-win_arm64.whl", hash = "sha256:78a42513018c41c2ffd262eb676442315cbfe3c44eed82385c2ed043bc63210a", size = 48347 }, - { url = "https://files.pythonhosted.org/packages/e9/44/77429fa0a58f941d6e1c58da9efe08597d2e86bf2b2cce6626834f49d07b/kiwisolver-1.4.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d2b0e12a42fb4e72d509fc994713d099cbb15ebf1103545e8a45f14da2dfca54", size = 122442 }, - { url = "https://files.pythonhosted.org/packages/e5/20/8c75caed8f2462d63c7fd65e16c832b8f76cda331ac9e615e914ee80bac9/kiwisolver-1.4.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2a8781ac3edc42ea4b90bc23e7d37b665d89423818e26eb6df90698aa2287c95", size = 65762 }, - { url = "https://files.pythonhosted.org/packages/f4/98/fe010f15dc7230f45bc4cf367b012d651367fd203caaa992fd1f5963560e/kiwisolver-1.4.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:46707a10836894b559e04b0fd143e343945c97fd170d69a2d26d640b4e297935", size = 64319 }, - { url = "https://files.pythonhosted.org/packages/8b/1b/b5d618f4e58c0675654c1e5051bcf42c776703edb21c02b8c74135541f60/kiwisolver-1.4.7-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef97b8df011141c9b0f6caf23b29379f87dd13183c978a30a3c546d2c47314cb", size = 1334260 }, - { url = "https://files.pythonhosted.org/packages/b8/01/946852b13057a162a8c32c4c8d2e9ed79f0bb5d86569a40c0b5fb103e373/kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab58c12a2cd0fc769089e6d38466c46d7f76aced0a1f54c77652446733d2d02", size = 1426589 }, - { url = "https://files.pythonhosted.org/packages/70/d1/c9f96df26b459e15cf8a965304e6e6f4eb291e0f7a9460b4ad97b047561e/kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:803b8e1459341c1bb56d1c5c010406d5edec8a0713a0945851290a7930679b51", size = 1541080 }, - { url = "https://files.pythonhosted.org/packages/d3/73/2686990eb8b02d05f3de759d6a23a4ee7d491e659007dd4c075fede4b5d0/kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f9a9e8a507420fe35992ee9ecb302dab68550dedc0da9e2880dd88071c5fb052", size = 1470049 }, - { url = "https://files.pythonhosted.org/packages/a7/4b/2db7af3ed3af7c35f388d5f53c28e155cd402a55432d800c543dc6deb731/kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18077b53dc3bb490e330669a99920c5e6a496889ae8c63b58fbc57c3d7f33a18", size = 1426376 }, - { url = "https://files.pythonhosted.org/packages/05/83/2857317d04ea46dc5d115f0df7e676997bbd968ced8e2bd6f7f19cfc8d7f/kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6af936f79086a89b3680a280c47ea90b4df7047b5bdf3aa5c524bbedddb9e545", size = 2222231 }, - { url = "https://files.pythonhosted.org/packages/0d/b5/866f86f5897cd4ab6d25d22e403404766a123f138bd6a02ecb2cdde52c18/kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:3abc5b19d24af4b77d1598a585b8a719beb8569a71568b66f4ebe1fb0449460b", size = 2368634 }, - { url = "https://files.pythonhosted.org/packages/c1/ee/73de8385403faba55f782a41260210528fe3273d0cddcf6d51648202d6d0/kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:933d4de052939d90afbe6e9d5273ae05fb836cc86c15b686edd4b3560cc0ee36", size = 2329024 }, - { url = "https://files.pythonhosted.org/packages/a1/e7/cd101d8cd2cdfaa42dc06c433df17c8303d31129c9fdd16c0ea37672af91/kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:65e720d2ab2b53f1f72fb5da5fb477455905ce2c88aaa671ff0a447c2c80e8e3", size = 2468484 }, - { url = "https://files.pythonhosted.org/packages/e1/72/84f09d45a10bc57a40bb58b81b99d8f22b58b2040c912b7eb97ebf625bf2/kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3bf1ed55088f214ba6427484c59553123fdd9b218a42bbc8c6496d6754b1e523", size = 2284078 }, - { url = "https://files.pythonhosted.org/packages/d2/d4/71828f32b956612dc36efd7be1788980cb1e66bfb3706e6dec9acad9b4f9/kiwisolver-1.4.7-cp311-cp311-win32.whl", hash = "sha256:4c00336b9dd5ad96d0a558fd18a8b6f711b7449acce4c157e7343ba92dd0cf3d", size = 46645 }, - { url = "https://files.pythonhosted.org/packages/a1/65/d43e9a20aabcf2e798ad1aff6c143ae3a42cf506754bcb6a7ed8259c8425/kiwisolver-1.4.7-cp311-cp311-win_amd64.whl", hash = "sha256:929e294c1ac1e9f615c62a4e4313ca1823ba37326c164ec720a803287c4c499b", size = 56022 }, - { url = "https://files.pythonhosted.org/packages/35/b3/9f75a2e06f1b4ca00b2b192bc2b739334127d27f1d0625627ff8479302ba/kiwisolver-1.4.7-cp311-cp311-win_arm64.whl", hash = "sha256:e33e8fbd440c917106b237ef1a2f1449dfbb9b6f6e1ce17c94cd6a1e0d438376", size = 48536 }, - { url = "https://files.pythonhosted.org/packages/97/9c/0a11c714cf8b6ef91001c8212c4ef207f772dd84540104952c45c1f0a249/kiwisolver-1.4.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:5360cc32706dab3931f738d3079652d20982511f7c0ac5711483e6eab08efff2", size = 121808 }, - { url = "https://files.pythonhosted.org/packages/f2/d8/0fe8c5f5d35878ddd135f44f2af0e4e1d379e1c7b0716f97cdcb88d4fd27/kiwisolver-1.4.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:942216596dc64ddb25adb215c3c783215b23626f8d84e8eff8d6d45c3f29f75a", size = 65531 }, - { url = "https://files.pythonhosted.org/packages/80/c5/57fa58276dfdfa612241d640a64ca2f76adc6ffcebdbd135b4ef60095098/kiwisolver-1.4.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:48b571ecd8bae15702e4f22d3ff6a0f13e54d3d00cd25216d5e7f658242065ee", size = 63894 }, - { url = "https://files.pythonhosted.org/packages/8b/e9/26d3edd4c4ad1c5b891d8747a4f81b1b0aba9fb9721de6600a4adc09773b/kiwisolver-1.4.7-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ad42ba922c67c5f219097b28fae965e10045ddf145d2928bfac2eb2e17673640", size = 1369296 }, - { url = "https://files.pythonhosted.org/packages/b6/67/3f4850b5e6cffb75ec40577ddf54f7b82b15269cc5097ff2e968ee32ea7d/kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:612a10bdae23404a72941a0fc8fa2660c6ea1217c4ce0dbcab8a8f6543ea9e7f", size = 1461450 }, - { url = "https://files.pythonhosted.org/packages/52/be/86cbb9c9a315e98a8dc6b1d23c43cffd91d97d49318854f9c37b0e41cd68/kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9e838bba3a3bac0fe06d849d29772eb1afb9745a59710762e4ba3f4cb8424483", size = 1579168 }, - { url = "https://files.pythonhosted.org/packages/0f/00/65061acf64bd5fd34c1f4ae53f20b43b0a017a541f242a60b135b9d1e301/kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:22f499f6157236c19f4bbbd472fa55b063db77a16cd74d49afe28992dff8c258", size = 1507308 }, - { url = "https://files.pythonhosted.org/packages/21/e4/c0b6746fd2eb62fe702118b3ca0cb384ce95e1261cfada58ff693aeec08a/kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693902d433cf585133699972b6d7c42a8b9f8f826ebcaf0132ff55200afc599e", size = 1464186 }, - { url = "https://files.pythonhosted.org/packages/0a/0f/529d0a9fffb4d514f2782c829b0b4b371f7f441d61aa55f1de1c614c4ef3/kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4e77f2126c3e0b0d055f44513ed349038ac180371ed9b52fe96a32aa071a5107", size = 2247877 }, - { url = "https://files.pythonhosted.org/packages/d1/e1/66603ad779258843036d45adcbe1af0d1a889a07af4635f8b4ec7dccda35/kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:657a05857bda581c3656bfc3b20e353c232e9193eb167766ad2dc58b56504948", size = 2404204 }, - { url = "https://files.pythonhosted.org/packages/8d/61/de5fb1ca7ad1f9ab7970e340a5b833d735df24689047de6ae71ab9d8d0e7/kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4bfa75a048c056a411f9705856abfc872558e33c055d80af6a380e3658766038", size = 2352461 }, - { url = "https://files.pythonhosted.org/packages/ba/d2/0edc00a852e369827f7e05fd008275f550353f1f9bcd55db9363d779fc63/kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:34ea1de54beef1c104422d210c47c7d2a4999bdecf42c7b5718fbe59a4cac383", size = 2501358 }, - { url = "https://files.pythonhosted.org/packages/84/15/adc15a483506aec6986c01fb7f237c3aec4d9ed4ac10b756e98a76835933/kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:90da3b5f694b85231cf93586dad5e90e2d71b9428f9aad96952c99055582f520", size = 2314119 }, - { url = "https://files.pythonhosted.org/packages/36/08/3a5bb2c53c89660863a5aa1ee236912269f2af8762af04a2e11df851d7b2/kiwisolver-1.4.7-cp312-cp312-win32.whl", hash = "sha256:18e0cca3e008e17fe9b164b55735a325140a5a35faad8de92dd80265cd5eb80b", size = 46367 }, - { url = "https://files.pythonhosted.org/packages/19/93/c05f0a6d825c643779fc3c70876bff1ac221f0e31e6f701f0e9578690d70/kiwisolver-1.4.7-cp312-cp312-win_amd64.whl", hash = "sha256:58cb20602b18f86f83a5c87d3ee1c766a79c0d452f8def86d925e6c60fbf7bfb", size = 55884 }, - { url = "https://files.pythonhosted.org/packages/d2/f9/3828d8f21b6de4279f0667fb50a9f5215e6fe57d5ec0d61905914f5b6099/kiwisolver-1.4.7-cp312-cp312-win_arm64.whl", hash = "sha256:f5a8b53bdc0b3961f8b6125e198617c40aeed638b387913bf1ce78afb1b0be2a", size = 48528 }, - { url = "https://files.pythonhosted.org/packages/ac/59/741b79775d67ab67ced9bb38552da688c0305c16e7ee24bba7a2be253fb7/kiwisolver-1.4.7-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:94252291e3fe68001b1dd747b4c0b3be12582839b95ad4d1b641924d68fd4643", size = 59491 }, - { url = "https://files.pythonhosted.org/packages/58/cc/fb239294c29a5656e99e3527f7369b174dd9cc7c3ef2dea7cb3c54a8737b/kiwisolver-1.4.7-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5b7dfa3b546da08a9f622bb6becdb14b3e24aaa30adba66749d38f3cc7ea9706", size = 57648 }, - { url = "https://files.pythonhosted.org/packages/3b/ef/2f009ac1f7aab9f81efb2d837301d255279d618d27b6015780115ac64bdd/kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd3de6481f4ed8b734da5df134cd5a6a64fe32124fe83dde1e5b5f29fe30b1e6", size = 84257 }, - { url = "https://files.pythonhosted.org/packages/81/e1/c64f50987f85b68b1c52b464bb5bf73e71570c0f7782d626d1eb283ad620/kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a91b5f9f1205845d488c928e8570dcb62b893372f63b8b6e98b863ebd2368ff2", size = 80906 }, - { url = "https://files.pythonhosted.org/packages/fd/71/1687c5c0a0be2cee39a5c9c389e546f9c6e215e46b691d00d9f646892083/kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40fa14dbd66b8b8f470d5fc79c089a66185619d31645f9b0773b88b19f7223c4", size = 79951 }, - { url = "https://files.pythonhosted.org/packages/ea/8b/d7497df4a1cae9367adf21665dd1f896c2a7aeb8769ad77b662c5e2bcce7/kiwisolver-1.4.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:eb542fe7933aa09d8d8f9d9097ef37532a7df6497819d16efe4359890a2f417a", size = 55715 }, +version = "1.4.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5c/3c/85844f1b0feb11ee581ac23fe5fce65cd049a200c1446708cc1b7f922875/kiwisolver-1.4.9.tar.gz", hash = "sha256:c3b22c26c6fd6811b0ae8363b95ca8ce4ea3c202d3d0975b2914310ceb1bcc4d", size = 97564, upload-time = "2025-08-10T21:27:49.279Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6f/ab/c80b0d5a9d8a1a65f4f815f2afff9798b12c3b9f31f1d304dd233dd920e2/kiwisolver-1.4.9-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eb14a5da6dc7642b0f3a18f13654847cd8b7a2550e2645a5bda677862b03ba16", size = 124167, upload-time = "2025-08-10T21:25:53.403Z" }, + { url = "https://files.pythonhosted.org/packages/a0/c0/27fe1a68a39cf62472a300e2879ffc13c0538546c359b86f149cc19f6ac3/kiwisolver-1.4.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:39a219e1c81ae3b103643d2aedb90f1ef22650deb266ff12a19e7773f3e5f089", size = 66579, upload-time = "2025-08-10T21:25:54.79Z" }, + { url = "https://files.pythonhosted.org/packages/31/a2/a12a503ac1fd4943c50f9822678e8015a790a13b5490354c68afb8489814/kiwisolver-1.4.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2405a7d98604b87f3fc28b1716783534b1b4b8510d8142adca34ee0bc3c87543", size = 65309, upload-time = "2025-08-10T21:25:55.76Z" }, + { url = "https://files.pythonhosted.org/packages/66/e1/e533435c0be77c3f64040d68d7a657771194a63c279f55573188161e81ca/kiwisolver-1.4.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:dc1ae486f9abcef254b5618dfb4113dd49f94c68e3e027d03cf0143f3f772b61", size = 1435596, upload-time = "2025-08-10T21:25:56.861Z" }, + { url = "https://files.pythonhosted.org/packages/67/1e/51b73c7347f9aabdc7215aa79e8b15299097dc2f8e67dee2b095faca9cb0/kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a1f570ce4d62d718dce3f179ee78dac3b545ac16c0c04bb363b7607a949c0d1", size = 1246548, upload-time = "2025-08-10T21:25:58.246Z" }, + { url = "https://files.pythonhosted.org/packages/21/aa/72a1c5d1e430294f2d32adb9542719cfb441b5da368d09d268c7757af46c/kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb27e7b78d716c591e88e0a09a2139c6577865d7f2e152488c2cc6257f460872", size = 1263618, upload-time = "2025-08-10T21:25:59.857Z" }, + { url = "https://files.pythonhosted.org/packages/a3/af/db1509a9e79dbf4c260ce0cfa3903ea8945f6240e9e59d1e4deb731b1a40/kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:15163165efc2f627eb9687ea5f3a28137217d217ac4024893d753f46bce9de26", size = 1317437, upload-time = "2025-08-10T21:26:01.105Z" }, + { url = "https://files.pythonhosted.org/packages/e0/f2/3ea5ee5d52abacdd12013a94130436e19969fa183faa1e7c7fbc89e9a42f/kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bdee92c56a71d2b24c33a7d4c2856bd6419d017e08caa7802d2963870e315028", size = 2195742, upload-time = "2025-08-10T21:26:02.675Z" }, + { url = "https://files.pythonhosted.org/packages/6f/9b/1efdd3013c2d9a2566aa6a337e9923a00590c516add9a1e89a768a3eb2fc/kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:412f287c55a6f54b0650bd9b6dce5aceddb95864a1a90c87af16979d37c89771", size = 2290810, upload-time = "2025-08-10T21:26:04.009Z" }, + { url = "https://files.pythonhosted.org/packages/fb/e5/cfdc36109ae4e67361f9bc5b41323648cb24a01b9ade18784657e022e65f/kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2c93f00dcba2eea70af2be5f11a830a742fe6b579a1d4e00f47760ef13be247a", size = 2461579, upload-time = "2025-08-10T21:26:05.317Z" }, + { url = "https://files.pythonhosted.org/packages/62/86/b589e5e86c7610842213994cdea5add00960076bef4ae290c5fa68589cac/kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f117e1a089d9411663a3207ba874f31be9ac8eaa5b533787024dc07aeb74f464", size = 2268071, upload-time = "2025-08-10T21:26:06.686Z" }, + { url = "https://files.pythonhosted.org/packages/3b/c6/f8df8509fd1eee6c622febe54384a96cfaf4d43bf2ccec7a0cc17e4715c9/kiwisolver-1.4.9-cp311-cp311-win_amd64.whl", hash = "sha256:be6a04e6c79819c9a8c2373317d19a96048e5a3f90bec587787e86a1153883c2", size = 73840, upload-time = "2025-08-10T21:26:07.94Z" }, + { url = "https://files.pythonhosted.org/packages/e2/2d/16e0581daafd147bc11ac53f032a2b45eabac897f42a338d0a13c1e5c436/kiwisolver-1.4.9-cp311-cp311-win_arm64.whl", hash = "sha256:0ae37737256ba2de764ddc12aed4956460277f00c4996d51a197e72f62f5eec7", size = 65159, upload-time = "2025-08-10T21:26:09.048Z" }, + { url = "https://files.pythonhosted.org/packages/86/c9/13573a747838aeb1c76e3267620daa054f4152444d1f3d1a2324b78255b5/kiwisolver-1.4.9-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ac5a486ac389dddcc5bef4f365b6ae3ffff2c433324fb38dd35e3fab7c957999", size = 123686, upload-time = "2025-08-10T21:26:10.034Z" }, + { url = "https://files.pythonhosted.org/packages/51/ea/2ecf727927f103ffd1739271ca19c424d0e65ea473fbaeea1c014aea93f6/kiwisolver-1.4.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f2ba92255faa7309d06fe44c3a4a97efe1c8d640c2a79a5ef728b685762a6fd2", size = 66460, upload-time = "2025-08-10T21:26:11.083Z" }, + { url = "https://files.pythonhosted.org/packages/5b/5a/51f5464373ce2aeb5194508298a508b6f21d3867f499556263c64c621914/kiwisolver-1.4.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a2899935e724dd1074cb568ce7ac0dce28b2cd6ab539c8e001a8578eb106d14", size = 64952, upload-time = "2025-08-10T21:26:12.058Z" }, + { url = "https://files.pythonhosted.org/packages/70/90/6d240beb0f24b74371762873e9b7f499f1e02166a2d9c5801f4dbf8fa12e/kiwisolver-1.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f6008a4919fdbc0b0097089f67a1eb55d950ed7e90ce2cc3e640abadd2757a04", size = 1474756, upload-time = "2025-08-10T21:26:13.096Z" }, + { url = "https://files.pythonhosted.org/packages/12/42/f36816eaf465220f683fb711efdd1bbf7a7005a2473d0e4ed421389bd26c/kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:67bb8b474b4181770f926f7b7d2f8c0248cbcb78b660fdd41a47054b28d2a752", size = 1276404, upload-time = "2025-08-10T21:26:14.457Z" }, + { url = "https://files.pythonhosted.org/packages/2e/64/bc2de94800adc830c476dce44e9b40fd0809cddeef1fde9fcf0f73da301f/kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2327a4a30d3ee07d2fbe2e7933e8a37c591663b96ce42a00bc67461a87d7df77", size = 1294410, upload-time = "2025-08-10T21:26:15.73Z" }, + { url = "https://files.pythonhosted.org/packages/5f/42/2dc82330a70aa8e55b6d395b11018045e58d0bb00834502bf11509f79091/kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7a08b491ec91b1d5053ac177afe5290adacf1f0f6307d771ccac5de30592d198", size = 1343631, upload-time = "2025-08-10T21:26:17.045Z" }, + { url = "https://files.pythonhosted.org/packages/22/fd/f4c67a6ed1aab149ec5a8a401c323cee7a1cbe364381bb6c9c0d564e0e20/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d8fc5c867c22b828001b6a38d2eaeb88160bf5783c6cb4a5e440efc981ce286d", size = 2224963, upload-time = "2025-08-10T21:26:18.737Z" }, + { url = "https://files.pythonhosted.org/packages/45/aa/76720bd4cb3713314677d9ec94dcc21ced3f1baf4830adde5bb9b2430a5f/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:3b3115b2581ea35bb6d1f24a4c90af37e5d9b49dcff267eeed14c3893c5b86ab", size = 2321295, upload-time = "2025-08-10T21:26:20.11Z" }, + { url = "https://files.pythonhosted.org/packages/80/19/d3ec0d9ab711242f56ae0dc2fc5d70e298bb4a1f9dfab44c027668c673a1/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:858e4c22fb075920b96a291928cb7dea5644e94c0ee4fcd5af7e865655e4ccf2", size = 2487987, upload-time = "2025-08-10T21:26:21.49Z" }, + { url = "https://files.pythonhosted.org/packages/39/e9/61e4813b2c97e86b6fdbd4dd824bf72d28bcd8d4849b8084a357bc0dd64d/kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ed0fecd28cc62c54b262e3736f8bb2512d8dcfdc2bcf08be5f47f96bf405b145", size = 2291817, upload-time = "2025-08-10T21:26:22.812Z" }, + { url = "https://files.pythonhosted.org/packages/a0/41/85d82b0291db7504da3c2defe35c9a8a5c9803a730f297bd823d11d5fb77/kiwisolver-1.4.9-cp312-cp312-win_amd64.whl", hash = "sha256:f68208a520c3d86ea51acf688a3e3002615a7f0238002cccc17affecc86a8a54", size = 73895, upload-time = "2025-08-10T21:26:24.37Z" }, + { url = "https://files.pythonhosted.org/packages/e2/92/5f3068cf15ee5cb624a0c7596e67e2a0bb2adee33f71c379054a491d07da/kiwisolver-1.4.9-cp312-cp312-win_arm64.whl", hash = "sha256:2c1a4f57df73965f3f14df20b80ee29e6a7930a57d2d9e8491a25f676e197c60", size = 64992, upload-time = "2025-08-10T21:26:25.732Z" }, + { url = "https://files.pythonhosted.org/packages/31/c1/c2686cda909742ab66c7388e9a1a8521a59eb89f8bcfbee28fc980d07e24/kiwisolver-1.4.9-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a5d0432ccf1c7ab14f9949eec60c5d1f924f17c037e9f8b33352fa05799359b8", size = 123681, upload-time = "2025-08-10T21:26:26.725Z" }, + { url = "https://files.pythonhosted.org/packages/ca/f0/f44f50c9f5b1a1860261092e3bc91ecdc9acda848a8b8c6abfda4a24dd5c/kiwisolver-1.4.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efb3a45b35622bb6c16dbfab491a8f5a391fe0e9d45ef32f4df85658232ca0e2", size = 66464, upload-time = "2025-08-10T21:26:27.733Z" }, + { url = "https://files.pythonhosted.org/packages/2d/7a/9d90a151f558e29c3936b8a47ac770235f436f2120aca41a6d5f3d62ae8d/kiwisolver-1.4.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1a12cf6398e8a0a001a059747a1cbf24705e18fe413bc22de7b3d15c67cffe3f", size = 64961, upload-time = "2025-08-10T21:26:28.729Z" }, + { url = "https://files.pythonhosted.org/packages/e9/e9/f218a2cb3a9ffbe324ca29a9e399fa2d2866d7f348ec3a88df87fc248fc5/kiwisolver-1.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b67e6efbf68e077dd71d1a6b37e43e1a99d0bff1a3d51867d45ee8908b931098", size = 1474607, upload-time = "2025-08-10T21:26:29.798Z" }, + { url = "https://files.pythonhosted.org/packages/d9/28/aac26d4c882f14de59041636292bc838db8961373825df23b8eeb807e198/kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5656aa670507437af0207645273ccdfee4f14bacd7f7c67a4306d0dcaeaf6eed", size = 1276546, upload-time = "2025-08-10T21:26:31.401Z" }, + { url = "https://files.pythonhosted.org/packages/8b/ad/8bfc1c93d4cc565e5069162f610ba2f48ff39b7de4b5b8d93f69f30c4bed/kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bfc08add558155345129c7803b3671cf195e6a56e7a12f3dde7c57d9b417f525", size = 1294482, upload-time = "2025-08-10T21:26:32.721Z" }, + { url = "https://files.pythonhosted.org/packages/da/f1/6aca55ff798901d8ce403206d00e033191f63d82dd708a186e0ed2067e9c/kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:40092754720b174e6ccf9e845d0d8c7d8e12c3d71e7fc35f55f3813e96376f78", size = 1343720, upload-time = "2025-08-10T21:26:34.032Z" }, + { url = "https://files.pythonhosted.org/packages/d1/91/eed031876c595c81d90d0f6fc681ece250e14bf6998c3d7c419466b523b7/kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:497d05f29a1300d14e02e6441cf0f5ee81c1ff5a304b0d9fb77423974684e08b", size = 2224907, upload-time = "2025-08-10T21:26:35.824Z" }, + { url = "https://files.pythonhosted.org/packages/e9/ec/4d1925f2e49617b9cca9c34bfa11adefad49d00db038e692a559454dfb2e/kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:bdd1a81a1860476eb41ac4bc1e07b3f07259e6d55bbf739b79c8aaedcf512799", size = 2321334, upload-time = "2025-08-10T21:26:37.534Z" }, + { url = "https://files.pythonhosted.org/packages/43/cb/450cd4499356f68802750c6ddc18647b8ea01ffa28f50d20598e0befe6e9/kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e6b93f13371d341afee3be9f7c5964e3fe61d5fa30f6a30eb49856935dfe4fc3", size = 2488313, upload-time = "2025-08-10T21:26:39.191Z" }, + { url = "https://files.pythonhosted.org/packages/71/67/fc76242bd99f885651128a5d4fa6083e5524694b7c88b489b1b55fdc491d/kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d75aa530ccfaa593da12834b86a0724f58bff12706659baa9227c2ccaa06264c", size = 2291970, upload-time = "2025-08-10T21:26:40.828Z" }, + { url = "https://files.pythonhosted.org/packages/75/bd/f1a5d894000941739f2ae1b65a32892349423ad49c2e6d0771d0bad3fae4/kiwisolver-1.4.9-cp313-cp313-win_amd64.whl", hash = "sha256:dd0a578400839256df88c16abddf9ba14813ec5f21362e1fe65022e00c883d4d", size = 73894, upload-time = "2025-08-10T21:26:42.33Z" }, + { url = "https://files.pythonhosted.org/packages/95/38/dce480814d25b99a391abbddadc78f7c117c6da34be68ca8b02d5848b424/kiwisolver-1.4.9-cp313-cp313-win_arm64.whl", hash = "sha256:d4188e73af84ca82468f09cadc5ac4db578109e52acb4518d8154698d3a87ca2", size = 64995, upload-time = "2025-08-10T21:26:43.889Z" }, + { url = "https://files.pythonhosted.org/packages/e2/37/7d218ce5d92dadc5ebdd9070d903e0c7cf7edfe03f179433ac4d13ce659c/kiwisolver-1.4.9-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:5a0f2724dfd4e3b3ac5a82436a8e6fd16baa7d507117e4279b660fe8ca38a3a1", size = 126510, upload-time = "2025-08-10T21:26:44.915Z" }, + { url = "https://files.pythonhosted.org/packages/23/b0/e85a2b48233daef4b648fb657ebbb6f8367696a2d9548a00b4ee0eb67803/kiwisolver-1.4.9-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:1b11d6a633e4ed84fc0ddafd4ebfd8ea49b3f25082c04ad12b8315c11d504dc1", size = 67903, upload-time = "2025-08-10T21:26:45.934Z" }, + { url = "https://files.pythonhosted.org/packages/44/98/f2425bc0113ad7de24da6bb4dae1343476e95e1d738be7c04d31a5d037fd/kiwisolver-1.4.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61874cdb0a36016354853593cffc38e56fc9ca5aa97d2c05d3dcf6922cd55a11", size = 66402, upload-time = "2025-08-10T21:26:47.101Z" }, + { url = "https://files.pythonhosted.org/packages/98/d8/594657886df9f34c4177cc353cc28ca7e6e5eb562d37ccc233bff43bbe2a/kiwisolver-1.4.9-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:60c439763a969a6af93b4881db0eed8fadf93ee98e18cbc35bc8da868d0c4f0c", size = 1582135, upload-time = "2025-08-10T21:26:48.665Z" }, + { url = "https://files.pythonhosted.org/packages/5c/c6/38a115b7170f8b306fc929e166340c24958347308ea3012c2b44e7e295db/kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92a2f997387a1b79a75e7803aa7ded2cfbe2823852ccf1ba3bcf613b62ae3197", size = 1389409, upload-time = "2025-08-10T21:26:50.335Z" }, + { url = "https://files.pythonhosted.org/packages/bf/3b/e04883dace81f24a568bcee6eb3001da4ba05114afa622ec9b6fafdc1f5e/kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a31d512c812daea6d8b3be3b2bfcbeb091dbb09177706569bcfc6240dcf8b41c", size = 1401763, upload-time = "2025-08-10T21:26:51.867Z" }, + { url = "https://files.pythonhosted.org/packages/9f/80/20ace48e33408947af49d7d15c341eaee69e4e0304aab4b7660e234d6288/kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:52a15b0f35dad39862d376df10c5230155243a2c1a436e39eb55623ccbd68185", size = 1453643, upload-time = "2025-08-10T21:26:53.592Z" }, + { url = "https://files.pythonhosted.org/packages/64/31/6ce4380a4cd1f515bdda976a1e90e547ccd47b67a1546d63884463c92ca9/kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a30fd6fdef1430fd9e1ba7b3398b5ee4e2887783917a687d86ba69985fb08748", size = 2330818, upload-time = "2025-08-10T21:26:55.051Z" }, + { url = "https://files.pythonhosted.org/packages/fa/e9/3f3fcba3bcc7432c795b82646306e822f3fd74df0ee81f0fa067a1f95668/kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cc9617b46837c6468197b5945e196ee9ca43057bb7d9d1ae688101e4e1dddf64", size = 2419963, upload-time = "2025-08-10T21:26:56.421Z" }, + { url = "https://files.pythonhosted.org/packages/99/43/7320c50e4133575c66e9f7dadead35ab22d7c012a3b09bb35647792b2a6d/kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:0ab74e19f6a2b027ea4f845a78827969af45ce790e6cb3e1ebab71bdf9f215ff", size = 2594639, upload-time = "2025-08-10T21:26:57.882Z" }, + { url = "https://files.pythonhosted.org/packages/65/d6/17ae4a270d4a987ef8a385b906d2bdfc9fce502d6dc0d3aea865b47f548c/kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dba5ee5d3981160c28d5490f0d1b7ed730c22470ff7f6cc26cfcfaacb9896a07", size = 2391741, upload-time = "2025-08-10T21:26:59.237Z" }, + { url = "https://files.pythonhosted.org/packages/2a/8f/8f6f491d595a9e5912971f3f863d81baddccc8a4d0c3749d6a0dd9ffc9df/kiwisolver-1.4.9-cp313-cp313t-win_arm64.whl", hash = "sha256:0749fd8f4218ad2e851e11cc4dc05c7cbc0cbc4267bdfdb31782e65aace4ee9c", size = 68646, upload-time = "2025-08-10T21:27:00.52Z" }, + { url = "https://files.pythonhosted.org/packages/a3/0f/36d89194b5a32c054ce93e586d4049b6c2c22887b0eb229c61c68afd3078/kiwisolver-1.4.9-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:720e05574713db64c356e86732c0f3c5252818d05f9df320f0ad8380641acea5", size = 60104, upload-time = "2025-08-10T21:27:43.287Z" }, + { url = "https://files.pythonhosted.org/packages/52/ba/4ed75f59e4658fd21fe7dde1fee0ac397c678ec3befba3fe6482d987af87/kiwisolver-1.4.9-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:17680d737d5335b552994a2008fab4c851bcd7de33094a82067ef3a576ff02fa", size = 58592, upload-time = "2025-08-10T21:27:44.314Z" }, + { url = "https://files.pythonhosted.org/packages/33/01/a8ea7c5ea32a9b45ceeaee051a04c8ed4320f5add3c51bfa20879b765b70/kiwisolver-1.4.9-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:85b5352f94e490c028926ea567fc569c52ec79ce131dadb968d3853e809518c2", size = 80281, upload-time = "2025-08-10T21:27:45.369Z" }, + { url = "https://files.pythonhosted.org/packages/da/e3/dbd2ecdce306f1d07a1aaf324817ee993aab7aee9db47ceac757deabafbe/kiwisolver-1.4.9-pp311-pypy311_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:464415881e4801295659462c49461a24fb107c140de781d55518c4b80cb6790f", size = 78009, upload-time = "2025-08-10T21:27:46.376Z" }, + { url = "https://files.pythonhosted.org/packages/da/e9/0d4add7873a73e462aeb45c036a2dead2562b825aa46ba326727b3f31016/kiwisolver-1.4.9-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:fb940820c63a9590d31d88b815e7a3aa5915cad3ce735ab45f0c730b39547de1", size = 73929, upload-time = "2025-08-10T21:27:48.236Z" }, +] + +[[package]] +name = "lark" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/af/60/bc7622aefb2aee1c0b4ba23c1446d3e30225c8770b38d7aedbfb65ca9d5a/lark-1.2.2.tar.gz", hash = "sha256:ca807d0162cd16cef15a8feecb862d7319e7a09bdb13aef927968e45040fed80", size = 252132, upload-time = "2024-08-13T19:49:00.652Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/00/d90b10b962b4277f5e64a78b6609968859ff86889f5b898c1a778c06ec00/lark-1.2.2-py3-none-any.whl", hash = "sha256:c2276486b02f0f1b90be155f2c8ba4a8e194d42775786db622faccd652d8e80c", size = 111036, upload-time = "2024-08-13T19:48:58.603Z" }, ] [[package]] name = "legacy-api-wrap" version = "1.4.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a4/07/fbc3cf8cf3759c5f234af9d94761f09f41e6d0aa912b2a9dfda19a48855a/legacy_api_wrap-1.4.1.tar.gz", hash = "sha256:9c40d67aa8312fec8763e87cbf28fea4b67710c79ca7a18137b573d150f3b2b4", size = 11003 } +sdist = { url = "https://files.pythonhosted.org/packages/a4/07/fbc3cf8cf3759c5f234af9d94761f09f41e6d0aa912b2a9dfda19a48855a/legacy_api_wrap-1.4.1.tar.gz", hash = "sha256:9c40d67aa8312fec8763e87cbf28fea4b67710c79ca7a18137b573d150f3b2b4", size = 11003, upload-time = "2024-11-22T13:40:06.911Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3c/1d/9324c70629dfe4395f9122ab331cf245d3cce6ded851aa8a0a8ae264c4e6/legacy_api_wrap-1.4.1-py3-none-any.whl", hash = "sha256:8ba214242e836cebfd3b64c1a1653fce955abb0f9e4c7dffb51f2ad014def0eb", size = 9986 }, + { url = "https://files.pythonhosted.org/packages/3c/1d/9324c70629dfe4395f9122ab331cf245d3cce6ded851aa8a0a8ae264c4e6/legacy_api_wrap-1.4.1-py3-none-any.whl", hash = "sha256:8ba214242e836cebfd3b64c1a1653fce955abb0f9e4c7dffb51f2ad014def0eb", size = 9986, upload-time = "2024-11-22T13:40:05.265Z" }, ] [[package]] name = "llvmlite" -version = "0.43.0" +version = "0.44.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/89/6a/95a3d3610d5c75293d5dbbb2a76480d5d4eeba641557b69fe90af6c5b84e/llvmlite-0.44.0.tar.gz", hash = "sha256:07667d66a5d150abed9157ab6c0b9393c9356f229784a4385c02f99e94fc94d4", size = 171880, upload-time = "2025-01-20T11:14:41.342Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b5/e2/86b245397052386595ad726f9742e5223d7aea999b18c518a50e96c3aca4/llvmlite-0.44.0-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:eed7d5f29136bda63b6d7804c279e2b72e08c952b7c5df61f45db408e0ee52f3", size = 28132305, upload-time = "2025-01-20T11:12:53.936Z" }, + { url = "https://files.pythonhosted.org/packages/ff/ec/506902dc6870249fbe2466d9cf66d531265d0f3a1157213c8f986250c033/llvmlite-0.44.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ace564d9fa44bb91eb6e6d8e7754977783c68e90a471ea7ce913bff30bd62427", size = 26201090, upload-time = "2025-01-20T11:12:59.847Z" }, + { url = "https://files.pythonhosted.org/packages/99/fe/d030f1849ebb1f394bb3f7adad5e729b634fb100515594aca25c354ffc62/llvmlite-0.44.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5d22c3bfc842668168a786af4205ec8e3ad29fb1bc03fd11fd48460d0df64c1", size = 42361858, upload-time = "2025-01-20T11:13:07.623Z" }, + { url = "https://files.pythonhosted.org/packages/d7/7a/ce6174664b9077fc673d172e4c888cb0b128e707e306bc33fff8c2035f0d/llvmlite-0.44.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f01a394e9c9b7b1d4e63c327b096d10f6f0ed149ef53d38a09b3749dcf8c9610", size = 41184200, upload-time = "2025-01-20T11:13:20.058Z" }, + { url = "https://files.pythonhosted.org/packages/5f/c6/258801143975a6d09a373f2641237992496e15567b907a4d401839d671b8/llvmlite-0.44.0-cp311-cp311-win_amd64.whl", hash = "sha256:d8489634d43c20cd0ad71330dde1d5bc7b9966937a263ff1ec1cebb90dc50955", size = 30331193, upload-time = "2025-01-20T11:13:26.976Z" }, + { url = "https://files.pythonhosted.org/packages/15/86/e3c3195b92e6e492458f16d233e58a1a812aa2bfbef9bdd0fbafcec85c60/llvmlite-0.44.0-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:1d671a56acf725bf1b531d5ef76b86660a5ab8ef19bb6a46064a705c6ca80aad", size = 28132297, upload-time = "2025-01-20T11:13:32.57Z" }, + { url = "https://files.pythonhosted.org/packages/d6/53/373b6b8be67b9221d12b24125fd0ec56b1078b660eeae266ec388a6ac9a0/llvmlite-0.44.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f79a728e0435493611c9f405168682bb75ffd1fbe6fc360733b850c80a026db", size = 26201105, upload-time = "2025-01-20T11:13:38.744Z" }, + { url = "https://files.pythonhosted.org/packages/cb/da/8341fd3056419441286c8e26bf436923021005ece0bff5f41906476ae514/llvmlite-0.44.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0143a5ef336da14deaa8ec26c5449ad5b6a2b564df82fcef4be040b9cacfea9", size = 42361901, upload-time = "2025-01-20T11:13:46.711Z" }, + { url = "https://files.pythonhosted.org/packages/53/ad/d79349dc07b8a395a99153d7ce8b01d6fcdc9f8231355a5df55ded649b61/llvmlite-0.44.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d752f89e31b66db6f8da06df8b39f9b91e78c5feea1bf9e8c1fba1d1c24c065d", size = 41184247, upload-time = "2025-01-20T11:13:56.159Z" }, + { url = "https://files.pythonhosted.org/packages/e2/3b/a9a17366af80127bd09decbe2a54d8974b6d8b274b39bf47fbaedeec6307/llvmlite-0.44.0-cp312-cp312-win_amd64.whl", hash = "sha256:eae7e2d4ca8f88f89d315b48c6b741dcb925d6a1042da694aa16ab3dd4cbd3a1", size = 30332380, upload-time = "2025-01-20T11:14:02.442Z" }, + { url = "https://files.pythonhosted.org/packages/89/24/4c0ca705a717514c2092b18476e7a12c74d34d875e05e4d742618ebbf449/llvmlite-0.44.0-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:319bddd44e5f71ae2689859b7203080716448a3cd1128fb144fe5c055219d516", size = 28132306, upload-time = "2025-01-20T11:14:09.035Z" }, + { url = "https://files.pythonhosted.org/packages/01/cf/1dd5a60ba6aee7122ab9243fd614abcf22f36b0437cbbe1ccf1e3391461c/llvmlite-0.44.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9c58867118bad04a0bb22a2e0068c693719658105e40009ffe95c7000fcde88e", size = 26201090, upload-time = "2025-01-20T11:14:15.401Z" }, + { url = "https://files.pythonhosted.org/packages/d2/1b/656f5a357de7135a3777bd735cc7c9b8f23b4d37465505bd0eaf4be9befe/llvmlite-0.44.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46224058b13c96af1365290bdfebe9a6264ae62fb79b2b55693deed11657a8bf", size = 42361904, upload-time = "2025-01-20T11:14:22.949Z" }, + { url = "https://files.pythonhosted.org/packages/d8/e1/12c5f20cb9168fb3464a34310411d5ad86e4163c8ff2d14a2b57e5cc6bac/llvmlite-0.44.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa0097052c32bf721a4efc03bd109d335dfa57d9bffb3d4c24cc680711b8b4fc", size = 41184245, upload-time = "2025-01-20T11:14:31.731Z" }, + { url = "https://files.pythonhosted.org/packages/d0/81/e66fc86539293282fd9cb7c9417438e897f369e79ffb62e1ae5e5154d4dd/llvmlite-0.44.0-cp313-cp313-win_amd64.whl", hash = "sha256:2fb7c4f2fb86cbae6dca3db9ab203eeea0e22d73b99bc2341cdf9de93612e930", size = 30331193, upload-time = "2025-01-20T11:14:38.578Z" }, +] + +[[package]] +name = "logistro" +version = "1.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9f/3d/f513755f285db51ab363a53e898b85562e950f79a2e6767a364530c2f645/llvmlite-0.43.0.tar.gz", hash = "sha256:ae2b5b5c3ef67354824fb75517c8db5fbe93bc02cd9671f3c62271626bc041d5", size = 157069 } +sdist = { url = "https://files.pythonhosted.org/packages/27/c1/aa8bc9e07e4b4bd9a3bc05804c483ba3f334c94dcd54995da856103a204d/logistro-1.1.0.tar.gz", hash = "sha256:ad51f0efa2bc705bea7c266e8a759cf539457cf7108202a5eec77bdf6300d774", size = 8269, upload-time = "2025-04-26T20:14:11.012Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/23/ff/6ca7e98998b573b4bd6566f15c35e5c8bea829663a6df0c7aa55ab559da9/llvmlite-0.43.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a289af9a1687c6cf463478f0fa8e8aa3b6fb813317b0d70bf1ed0759eab6f761", size = 31064408 }, - { url = "https://files.pythonhosted.org/packages/ca/5c/a27f9257f86f0cda3f764ff21d9f4217b9f6a0d45e7a39ecfa7905f524ce/llvmlite-0.43.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d4fd101f571a31acb1559ae1af30f30b1dc4b3186669f92ad780e17c81e91bc", size = 28793153 }, - { url = "https://files.pythonhosted.org/packages/7e/3c/4410f670ad0a911227ea2ecfcba9f672a77cf1924df5280c4562032ec32d/llvmlite-0.43.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d434ec7e2ce3cc8f452d1cd9a28591745de022f931d67be688a737320dfcead", size = 42857276 }, - { url = "https://files.pythonhosted.org/packages/c6/21/2ffbab5714e72f2483207b4a1de79b2eecd9debbf666ff4e7067bcc5c134/llvmlite-0.43.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6912a87782acdff6eb8bf01675ed01d60ca1f2551f8176a300a886f09e836a6a", size = 43871781 }, - { url = "https://files.pythonhosted.org/packages/f2/26/b5478037c453554a61625ef1125f7e12bb1429ae11c6376f47beba9b0179/llvmlite-0.43.0-cp310-cp310-win_amd64.whl", hash = "sha256:14f0e4bf2fd2d9a75a3534111e8ebeb08eda2f33e9bdd6dfa13282afacdde0ed", size = 28123487 }, - { url = "https://files.pythonhosted.org/packages/95/8c/de3276d773ab6ce3ad676df5fab5aac19696b2956319d65d7dd88fb10f19/llvmlite-0.43.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3e8d0618cb9bfe40ac38a9633f2493d4d4e9fcc2f438d39a4e854f39cc0f5f98", size = 31064409 }, - { url = "https://files.pythonhosted.org/packages/ee/e1/38deed89ced4cf378c61e232265cfe933ccde56ae83c901aa68b477d14b1/llvmlite-0.43.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0a9a1a39d4bf3517f2af9d23d479b4175ead205c592ceeb8b89af48a327ea57", size = 28793149 }, - { url = "https://files.pythonhosted.org/packages/2f/b2/4429433eb2dc8379e2cb582502dca074c23837f8fd009907f78a24de4c25/llvmlite-0.43.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1da416ab53e4f7f3bc8d4eeba36d801cc1894b9fbfbf2022b29b6bad34a7df2", size = 42857277 }, - { url = "https://files.pythonhosted.org/packages/6b/99/5d00a7d671b1ba1751fc9f19d3b36f3300774c6eebe2bcdb5f6191763eb4/llvmlite-0.43.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:977525a1e5f4059316b183fb4fd34fa858c9eade31f165427a3977c95e3ee749", size = 43871781 }, - { url = "https://files.pythonhosted.org/packages/20/ab/ed5ed3688c6ba4f0b8d789da19fd8e30a9cf7fc5852effe311bc5aefe73e/llvmlite-0.43.0-cp311-cp311-win_amd64.whl", hash = "sha256:d5bd550001d26450bd90777736c69d68c487d17bf371438f975229b2b8241a91", size = 28107433 }, - { url = "https://files.pythonhosted.org/packages/0b/67/9443509e5d2b6d8587bae3ede5598fa8bd586b1c7701696663ea8af15b5b/llvmlite-0.43.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f99b600aa7f65235a5a05d0b9a9f31150c390f31261f2a0ba678e26823ec38f7", size = 31064409 }, - { url = "https://files.pythonhosted.org/packages/a2/9c/24139d3712d2d352e300c39c0e00d167472c08b3bd350c3c33d72c88ff8d/llvmlite-0.43.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:35d80d61d0cda2d767f72de99450766250560399edc309da16937b93d3b676e7", size = 28793145 }, - { url = "https://files.pythonhosted.org/packages/bf/f1/4c205a48488e574ee9f6505d50e84370a978c90f08dab41a42d8f2c576b6/llvmlite-0.43.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eccce86bba940bae0d8d48ed925f21dbb813519169246e2ab292b5092aba121f", size = 42857276 }, - { url = "https://files.pythonhosted.org/packages/00/5f/323c4d56e8401c50185fd0e875fcf06b71bf825a863699be1eb10aa2a9cb/llvmlite-0.43.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df6509e1507ca0760787a199d19439cc887bfd82226f5af746d6977bd9f66844", size = 43871781 }, - { url = "https://files.pythonhosted.org/packages/c6/94/dea10e263655ce78d777e78d904903faae39d1fc440762be4a9dc46bed49/llvmlite-0.43.0-cp312-cp312-win_amd64.whl", hash = "sha256:7a2872ee80dcf6b5dbdc838763d26554c2a18aa833d31a2635bff16aafefb9c9", size = 28107442 }, + { url = "https://files.pythonhosted.org/packages/bc/df/e51691ab004d74fa25b751527d041ad1b4d84ee86cbcb8630ab0d7d5188e/logistro-1.1.0-py3-none-any.whl", hash = "sha256:4f88541fe7f3c545561b754d86121abd9c6d4d8b312381046a78dcd794fddc7c", size = 7894, upload-time = "2025-04-26T20:14:09.363Z" }, ] [[package]] name = "loguru" -version = "0.7.2" +version = "0.7.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, { name = "win32-setctime", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9e/30/d87a423766b24db416a46e9335b9602b054a72b96a88a241f2b09b560fa8/loguru-0.7.2.tar.gz", hash = "sha256:e671a53522515f34fd406340ee968cb9ecafbc4b36c679da03c18fd8d0bd51ac", size = 145103 } +sdist = { url = "https://files.pythonhosted.org/packages/3a/05/a1dae3dffd1116099471c643b8924f5aa6524411dc6c63fdae648c4f1aca/loguru-0.7.3.tar.gz", hash = "sha256:19480589e77d47b8d85b2c827ad95d49bf31b0dcde16593892eb51dd18706eb6", size = 63559, upload-time = "2024-12-06T11:20:56.608Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/03/0a/4f6fed21aa246c6b49b561ca55facacc2a44b87d65b8b92362a8e99ba202/loguru-0.7.2-py3-none-any.whl", hash = "sha256:003d71e3d3ed35f0f8984898359d65b79e5b21943f78af86aa5491210429b8eb", size = 62549 }, + { url = "https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl", hash = "sha256:31a33c10c8e1e10422bfd431aeb5d351c7cf7fa671e3c4df004162264b28220c", size = 61595, upload-time = "2024-12-06T11:20:54.538Z" }, ] [[package]] name = "markdown-it-py" -version = "3.0.0" +version = "4.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mdurl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596 } +sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528 }, + { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, ] [[package]] name = "markupsafe" version = "3.0.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/90/d08277ce111dd22f77149fd1a5d4653eeb3b3eaacbdfcbae5afb2600eebd/MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", size = 14357 }, - { url = "https://files.pythonhosted.org/packages/04/e1/6e2194baeae0bca1fae6629dc0cbbb968d4d941469cbab11a3872edff374/MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", size = 12393 }, - { url = "https://files.pythonhosted.org/packages/1d/69/35fa85a8ece0a437493dc61ce0bb6d459dcba482c34197e3efc829aa357f/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", size = 21732 }, - { url = "https://files.pythonhosted.org/packages/22/35/137da042dfb4720b638d2937c38a9c2df83fe32d20e8c8f3185dbfef05f7/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", size = 20866 }, - { url = "https://files.pythonhosted.org/packages/29/28/6d029a903727a1b62edb51863232152fd335d602def598dade38996887f0/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", size = 20964 }, - { url = "https://files.pythonhosted.org/packages/cc/cd/07438f95f83e8bc028279909d9c9bd39e24149b0d60053a97b2bc4f8aa51/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", size = 21977 }, - { url = "https://files.pythonhosted.org/packages/29/01/84b57395b4cc062f9c4c55ce0df7d3108ca32397299d9df00fedd9117d3d/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", size = 21366 }, - { url = "https://files.pythonhosted.org/packages/bd/6e/61ebf08d8940553afff20d1fb1ba7294b6f8d279df9fd0c0db911b4bbcfd/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", size = 21091 }, - { url = "https://files.pythonhosted.org/packages/11/23/ffbf53694e8c94ebd1e7e491de185124277964344733c45481f32ede2499/MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50", size = 15065 }, - { url = "https://files.pythonhosted.org/packages/44/06/e7175d06dd6e9172d4a69a72592cb3f7a996a9c396eee29082826449bbc3/MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", size = 15514 }, - { url = "https://files.pythonhosted.org/packages/6b/28/bbf83e3f76936960b850435576dd5e67034e200469571be53f69174a2dfd/MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", size = 14353 }, - { url = "https://files.pythonhosted.org/packages/6c/30/316d194b093cde57d448a4c3209f22e3046c5bb2fb0820b118292b334be7/MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", size = 12392 }, - { url = "https://files.pythonhosted.org/packages/f2/96/9cdafba8445d3a53cae530aaf83c38ec64c4d5427d975c974084af5bc5d2/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", size = 23984 }, - { url = "https://files.pythonhosted.org/packages/f1/a4/aefb044a2cd8d7334c8a47d3fb2c9f328ac48cb349468cc31c20b539305f/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", size = 23120 }, - { url = "https://files.pythonhosted.org/packages/8d/21/5e4851379f88f3fad1de30361db501300d4f07bcad047d3cb0449fc51f8c/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", size = 23032 }, - { url = "https://files.pythonhosted.org/packages/00/7b/e92c64e079b2d0d7ddf69899c98842f3f9a60a1ae72657c89ce2655c999d/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", size = 24057 }, - { url = "https://files.pythonhosted.org/packages/f9/ac/46f960ca323037caa0a10662ef97d0a4728e890334fc156b9f9e52bcc4ca/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", size = 23359 }, - { url = "https://files.pythonhosted.org/packages/69/84/83439e16197337b8b14b6a5b9c2105fff81d42c2a7c5b58ac7b62ee2c3b1/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", size = 23306 }, - { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094 }, - { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521 }, - { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274 }, - { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348 }, - { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149 }, - { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118 }, - { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993 }, - { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178 }, - { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319 }, - { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352 }, - { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097 }, - { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601 }, +sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537, upload-time = "2024-10-18T15:21:54.129Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6b/28/bbf83e3f76936960b850435576dd5e67034e200469571be53f69174a2dfd/MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", size = 14353, upload-time = "2024-10-18T15:21:02.187Z" }, + { url = "https://files.pythonhosted.org/packages/6c/30/316d194b093cde57d448a4c3209f22e3046c5bb2fb0820b118292b334be7/MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", size = 12392, upload-time = "2024-10-18T15:21:02.941Z" }, + { url = "https://files.pythonhosted.org/packages/f2/96/9cdafba8445d3a53cae530aaf83c38ec64c4d5427d975c974084af5bc5d2/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", size = 23984, upload-time = "2024-10-18T15:21:03.953Z" }, + { url = "https://files.pythonhosted.org/packages/f1/a4/aefb044a2cd8d7334c8a47d3fb2c9f328ac48cb349468cc31c20b539305f/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", size = 23120, upload-time = "2024-10-18T15:21:06.495Z" }, + { url = "https://files.pythonhosted.org/packages/8d/21/5e4851379f88f3fad1de30361db501300d4f07bcad047d3cb0449fc51f8c/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", size = 23032, upload-time = "2024-10-18T15:21:07.295Z" }, + { url = "https://files.pythonhosted.org/packages/00/7b/e92c64e079b2d0d7ddf69899c98842f3f9a60a1ae72657c89ce2655c999d/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", size = 24057, upload-time = "2024-10-18T15:21:08.073Z" }, + { url = "https://files.pythonhosted.org/packages/f9/ac/46f960ca323037caa0a10662ef97d0a4728e890334fc156b9f9e52bcc4ca/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", size = 23359, upload-time = "2024-10-18T15:21:09.318Z" }, + { url = "https://files.pythonhosted.org/packages/69/84/83439e16197337b8b14b6a5b9c2105fff81d42c2a7c5b58ac7b62ee2c3b1/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", size = 23306, upload-time = "2024-10-18T15:21:10.185Z" }, + { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094, upload-time = "2024-10-18T15:21:11.005Z" }, + { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521, upload-time = "2024-10-18T15:21:12.911Z" }, + { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274, upload-time = "2024-10-18T15:21:13.777Z" }, + { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348, upload-time = "2024-10-18T15:21:14.822Z" }, + { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149, upload-time = "2024-10-18T15:21:15.642Z" }, + { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118, upload-time = "2024-10-18T15:21:17.133Z" }, + { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993, upload-time = "2024-10-18T15:21:18.064Z" }, + { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178, upload-time = "2024-10-18T15:21:18.859Z" }, + { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319, upload-time = "2024-10-18T15:21:19.671Z" }, + { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352, upload-time = "2024-10-18T15:21:20.971Z" }, + { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097, upload-time = "2024-10-18T15:21:22.646Z" }, + { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601, upload-time = "2024-10-18T15:21:23.499Z" }, + { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274, upload-time = "2024-10-18T15:21:24.577Z" }, + { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352, upload-time = "2024-10-18T15:21:25.382Z" }, + { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122, upload-time = "2024-10-18T15:21:26.199Z" }, + { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085, upload-time = "2024-10-18T15:21:27.029Z" }, + { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978, upload-time = "2024-10-18T15:21:27.846Z" }, + { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208, upload-time = "2024-10-18T15:21:28.744Z" }, + { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357, upload-time = "2024-10-18T15:21:29.545Z" }, + { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344, upload-time = "2024-10-18T15:21:30.366Z" }, + { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101, upload-time = "2024-10-18T15:21:31.207Z" }, + { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603, upload-time = "2024-10-18T15:21:32.032Z" }, + { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510, upload-time = "2024-10-18T15:21:33.625Z" }, + { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486, upload-time = "2024-10-18T15:21:34.611Z" }, + { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480, upload-time = "2024-10-18T15:21:35.398Z" }, + { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914, upload-time = "2024-10-18T15:21:36.231Z" }, + { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796, upload-time = "2024-10-18T15:21:37.073Z" }, + { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473, upload-time = "2024-10-18T15:21:37.932Z" }, + { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114, upload-time = "2024-10-18T15:21:39.799Z" }, + { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098, upload-time = "2024-10-18T15:21:40.813Z" }, + { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208, upload-time = "2024-10-18T15:21:41.814Z" }, + { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739, upload-time = "2024-10-18T15:21:42.784Z" }, ] [[package]] name = "matplotlib" -version = "3.8.4" +version = "3.10.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "contourpy" }, @@ -1406,26 +1655,39 @@ dependencies = [ { name = "pyparsing" }, { name = "python-dateutil" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/38/4f/8487737a74d8be4ab5fbe6019b0fae305c1604cf7209500969b879b5f462/matplotlib-3.8.4.tar.gz", hash = "sha256:8aac397d5e9ec158960e31c381c5ffc52ddd52bd9a47717e2a694038167dffea", size = 35934425 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/67/c0/1f88491656d21a2fecd90fbfae999b2f87bc44d439ef301ec8e0e4a937a0/matplotlib-3.8.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:abc9d838f93583650c35eca41cfcec65b2e7cb50fd486da6f0c49b5e1ed23014", size = 7603557 }, - { url = "https://files.pythonhosted.org/packages/86/9c/aa059a4fb8154d5875a5ddd33f8d0a42d77c0225fe4325e9b9358f39b0bf/matplotlib-3.8.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f65c9f002d281a6e904976007b2d46a1ee2bcea3a68a8c12dda24709ddc9106", size = 7497421 }, - { url = "https://files.pythonhosted.org/packages/0b/67/ded5217d42de1532193cd87db925c67997d23c68b20c3eaa9e4c6a0adb67/matplotlib-3.8.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce1edd9f5383b504dbc26eeea404ed0a00656c526638129028b758fd43fc5f10", size = 11377985 }, - { url = "https://files.pythonhosted.org/packages/d6/07/061f97211f942101070a46fecd813a6b1bd83590ed7b07c473cabd707fe7/matplotlib-3.8.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ecd79298550cba13a43c340581a3ec9c707bd895a6a061a78fa2524660482fc0", size = 11608003 }, - { url = "https://files.pythonhosted.org/packages/9a/d3/5d0bb1d905e219543fdfd7ab04e9d641a766367c83a5ffbcea60d2b2cf2d/matplotlib-3.8.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:90df07db7b599fe7035d2f74ab7e438b656528c68ba6bb59b7dc46af39ee48ef", size = 9535368 }, - { url = "https://files.pythonhosted.org/packages/62/5a/a5108ae3db37f35f8a2be8a57d62da327af239214c9661464ce09ee32d7d/matplotlib-3.8.4-cp310-cp310-win_amd64.whl", hash = "sha256:ac24233e8f2939ac4fd2919eed1e9c0871eac8057666070e94cbf0b33dd9c338", size = 7656037 }, - { url = "https://files.pythonhosted.org/packages/36/11/62250ea25780d4b59c2c6044ec161235c47cc05a18d0ec0a05657de75b7d/matplotlib-3.8.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:72f9322712e4562e792b2961971891b9fbbb0e525011e09ea0d1f416c4645661", size = 7606117 }, - { url = "https://files.pythonhosted.org/packages/14/60/12d4f27b859a74359306662da69c2d08826a2b05cfe7f96e66b490f41573/matplotlib-3.8.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:232ce322bfd020a434caaffbd9a95333f7c2491e59cfc014041d95e38ab90d1c", size = 7500108 }, - { url = "https://files.pythonhosted.org/packages/4e/ba/9e4f7f34dccf2d2768504410410db8d551c940457a2bec658dc4fa3b5aa2/matplotlib-3.8.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6addbd5b488aedb7f9bc19f91cd87ea476206f45d7116fcfe3d31416702a82fa", size = 11382998 }, - { url = "https://files.pythonhosted.org/packages/80/3b/e363612ac1a514abfb5505aa209dd5b724b3232a6de98710d7759559706a/matplotlib-3.8.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc4ccdc64e3039fc303defd119658148f2349239871db72cd74e2eeaa9b80b71", size = 11613309 }, - { url = "https://files.pythonhosted.org/packages/32/4c/63164901acadb3ada55c5e0fd6b7f29c9033d7e131302884cd735611b77a/matplotlib-3.8.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b7a2a253d3b36d90c8993b4620183b55665a429da8357a4f621e78cd48b2b30b", size = 9546019 }, - { url = "https://files.pythonhosted.org/packages/2d/d5/6227732ecab9165586966ccb54301e3164f61b470c954c4cf6940654fbe1/matplotlib-3.8.4-cp311-cp311-win_amd64.whl", hash = "sha256:8080d5081a86e690d7688ffa542532e87f224c38a6ed71f8fbed34dd1d9fedae", size = 7658174 }, - { url = "https://files.pythonhosted.org/packages/91/eb/65f3bd78ce757dadd455c220273349428384b162485cd8aa380b61a867ed/matplotlib-3.8.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:6485ac1f2e84676cff22e693eaa4fbed50ef5dc37173ce1f023daef4687df616", size = 7604083 }, - { url = "https://files.pythonhosted.org/packages/da/2b/2bb6073ca8d336da07ace7d98bf7bb9da8233f55876bb3db6a5ee924f3e9/matplotlib-3.8.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c89ee9314ef48c72fe92ce55c4e95f2f39d70208f9f1d9db4e64079420d8d732", size = 7496013 }, - { url = "https://files.pythonhosted.org/packages/61/cd/976d3a9c10328da1d2fe183f7c92c45f1e125536226a6eb3a820c4753cd1/matplotlib-3.8.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50bac6e4d77e4262c4340d7a985c30912054745ec99756ce213bfbc3cb3808eb", size = 11376749 }, - { url = "https://files.pythonhosted.org/packages/cd/ba/412149958e951876096198609b958b90a8a2c9bc07a96eeeaa9e2c480f30/matplotlib-3.8.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f51c4c869d4b60d769f7b4406eec39596648d9d70246428745a681c327a8ad30", size = 11600837 }, - { url = "https://files.pythonhosted.org/packages/dc/4f/e5b56ca109d8ab6bae37f519f15b891fc18809ddb8bc1aa26e0bfca83e25/matplotlib-3.8.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b12ba985837e4899b762b81f5b2845bd1a28f4fdd1a126d9ace64e9c4eb2fb25", size = 9538883 }, - { url = "https://files.pythonhosted.org/packages/7d/ca/e7bd1876a341ed8c456095962a582696cac1691cb6e55bd5ead15a755c5d/matplotlib-3.8.4-cp312-cp312-win_amd64.whl", hash = "sha256:7a6769f58ce51791b4cb8b4d7642489df347697cd3e23d88266aaaee93b41d9a", size = 7659712 }, +sdist = { url = "https://files.pythonhosted.org/packages/a0/59/c3e6453a9676ffba145309a73c462bb407f4400de7de3f2b41af70720a3c/matplotlib-3.10.6.tar.gz", hash = "sha256:ec01b645840dd1996df21ee37f208cd8ba57644779fa20464010638013d3203c", size = 34804264, upload-time = "2025-08-30T00:14:25.137Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/80/d6/5d3665aa44c49005aaacaa68ddea6fcb27345961cd538a98bb0177934ede/matplotlib-3.10.6-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:905b60d1cb0ee604ce65b297b61cf8be9f4e6cfecf95a3fe1c388b5266bc8f4f", size = 8257527, upload-time = "2025-08-30T00:12:45.31Z" }, + { url = "https://files.pythonhosted.org/packages/8c/af/30ddefe19ca67eebd70047dabf50f899eaff6f3c5e6a1a7edaecaf63f794/matplotlib-3.10.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7bac38d816637343e53d7185d0c66677ff30ffb131044a81898b5792c956ba76", size = 8119583, upload-time = "2025-08-30T00:12:47.236Z" }, + { url = "https://files.pythonhosted.org/packages/d3/29/4a8650a3dcae97fa4f375d46efcb25920d67b512186f8a6788b896062a81/matplotlib-3.10.6-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:942a8de2b5bfff1de31d95722f702e2966b8a7e31f4e68f7cd963c7cd8861cf6", size = 8692682, upload-time = "2025-08-30T00:12:48.781Z" }, + { url = "https://files.pythonhosted.org/packages/aa/d3/b793b9cb061cfd5d42ff0f69d1822f8d5dbc94e004618e48a97a8373179a/matplotlib-3.10.6-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a3276c85370bc0dfca051ec65c5817d1e0f8f5ce1b7787528ec8ed2d524bbc2f", size = 9521065, upload-time = "2025-08-30T00:12:50.602Z" }, + { url = "https://files.pythonhosted.org/packages/f7/c5/53de5629f223c1c66668d46ac2621961970d21916a4bc3862b174eb2a88f/matplotlib-3.10.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9df5851b219225731f564e4b9e7f2ac1e13c9e6481f941b5631a0f8e2d9387ce", size = 9576888, upload-time = "2025-08-30T00:12:52.92Z" }, + { url = "https://files.pythonhosted.org/packages/fc/8e/0a18d6d7d2d0a2e66585032a760d13662e5250c784d53ad50434e9560991/matplotlib-3.10.6-cp311-cp311-win_amd64.whl", hash = "sha256:abb5d9478625dd9c9eb51a06d39aae71eda749ae9b3138afb23eb38824026c7e", size = 8115158, upload-time = "2025-08-30T00:12:54.863Z" }, + { url = "https://files.pythonhosted.org/packages/07/b3/1a5107bb66c261e23b9338070702597a2d374e5aa7004b7adfc754fbed02/matplotlib-3.10.6-cp311-cp311-win_arm64.whl", hash = "sha256:886f989ccfae63659183173bb3fced7fd65e9eb793c3cc21c273add368536951", size = 7992444, upload-time = "2025-08-30T00:12:57.067Z" }, + { url = "https://files.pythonhosted.org/packages/ea/1a/7042f7430055d567cc3257ac409fcf608599ab27459457f13772c2d9778b/matplotlib-3.10.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:31ca662df6a80bd426f871105fdd69db7543e28e73a9f2afe80de7e531eb2347", size = 8272404, upload-time = "2025-08-30T00:12:59.112Z" }, + { url = "https://files.pythonhosted.org/packages/a9/5d/1d5f33f5b43f4f9e69e6a5fe1fb9090936ae7bc8e2ff6158e7a76542633b/matplotlib-3.10.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1678bb61d897bb4ac4757b5ecfb02bfb3fddf7f808000fb81e09c510712fda75", size = 8128262, upload-time = "2025-08-30T00:13:01.141Z" }, + { url = "https://files.pythonhosted.org/packages/67/c3/135fdbbbf84e0979712df58e5e22b4f257b3f5e52a3c4aacf1b8abec0d09/matplotlib-3.10.6-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:56cd2d20842f58c03d2d6e6c1f1cf5548ad6f66b91e1e48f814e4fb5abd1cb95", size = 8697008, upload-time = "2025-08-30T00:13:03.24Z" }, + { url = "https://files.pythonhosted.org/packages/9c/be/c443ea428fb2488a3ea7608714b1bd85a82738c45da21b447dc49e2f8e5d/matplotlib-3.10.6-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:662df55604a2f9a45435566d6e2660e41efe83cd94f4288dfbf1e6d1eae4b0bb", size = 9530166, upload-time = "2025-08-30T00:13:05.951Z" }, + { url = "https://files.pythonhosted.org/packages/a9/35/48441422b044d74034aea2a3e0d1a49023f12150ebc58f16600132b9bbaf/matplotlib-3.10.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:08f141d55148cd1fc870c3387d70ca4df16dee10e909b3b038782bd4bda6ea07", size = 9593105, upload-time = "2025-08-30T00:13:08.356Z" }, + { url = "https://files.pythonhosted.org/packages/45/c3/994ef20eb4154ab84cc08d033834555319e4af970165e6c8894050af0b3c/matplotlib-3.10.6-cp312-cp312-win_amd64.whl", hash = "sha256:590f5925c2d650b5c9d813c5b3b5fc53f2929c3f8ef463e4ecfa7e052044fb2b", size = 8122784, upload-time = "2025-08-30T00:13:10.367Z" }, + { url = "https://files.pythonhosted.org/packages/57/b8/5c85d9ae0e40f04e71bedb053aada5d6bab1f9b5399a0937afb5d6b02d98/matplotlib-3.10.6-cp312-cp312-win_arm64.whl", hash = "sha256:f44c8d264a71609c79a78d50349e724f5d5fc3684ead7c2a473665ee63d868aa", size = 7992823, upload-time = "2025-08-30T00:13:12.24Z" }, + { url = "https://files.pythonhosted.org/packages/a0/db/18380e788bb837e724358287b08e223b32bc8dccb3b0c12fa8ca20bc7f3b/matplotlib-3.10.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:819e409653c1106c8deaf62e6de6b8611449c2cd9939acb0d7d4e57a3d95cc7a", size = 8273231, upload-time = "2025-08-30T00:13:13.881Z" }, + { url = "https://files.pythonhosted.org/packages/d3/0f/38dd49445b297e0d4f12a322c30779df0d43cb5873c7847df8a82e82ec67/matplotlib-3.10.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:59c8ac8382fefb9cb71308dde16a7c487432f5255d8f1fd32473523abecfecdf", size = 8128730, upload-time = "2025-08-30T00:13:15.556Z" }, + { url = "https://files.pythonhosted.org/packages/e5/b8/9eea6630198cb303d131d95d285a024b3b8645b1763a2916fddb44ca8760/matplotlib-3.10.6-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:84e82d9e0fd70c70bc55739defbd8055c54300750cbacf4740c9673a24d6933a", size = 8698539, upload-time = "2025-08-30T00:13:17.297Z" }, + { url = "https://files.pythonhosted.org/packages/71/34/44c7b1f075e1ea398f88aeabcc2907c01b9cc99e2afd560c1d49845a1227/matplotlib-3.10.6-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25f7a3eb42d6c1c56e89eacd495661fc815ffc08d9da750bca766771c0fd9110", size = 9529702, upload-time = "2025-08-30T00:13:19.248Z" }, + { url = "https://files.pythonhosted.org/packages/b5/7f/e5c2dc9950c7facaf8b461858d1b92c09dd0cf174fe14e21953b3dda06f7/matplotlib-3.10.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f9c862d91ec0b7842920a4cfdaaec29662195301914ea54c33e01f1a28d014b2", size = 9593742, upload-time = "2025-08-30T00:13:21.181Z" }, + { url = "https://files.pythonhosted.org/packages/ff/1d/70c28528794f6410ee2856cd729fa1f1756498b8d3126443b0a94e1a8695/matplotlib-3.10.6-cp313-cp313-win_amd64.whl", hash = "sha256:1b53bd6337eba483e2e7d29c5ab10eee644bc3a2491ec67cc55f7b44583ffb18", size = 8122753, upload-time = "2025-08-30T00:13:23.44Z" }, + { url = "https://files.pythonhosted.org/packages/e8/74/0e1670501fc7d02d981564caf7c4df42974464625935424ca9654040077c/matplotlib-3.10.6-cp313-cp313-win_arm64.whl", hash = "sha256:cbd5eb50b7058b2892ce45c2f4e92557f395c9991f5c886d1bb74a1582e70fd6", size = 7992973, upload-time = "2025-08-30T00:13:26.632Z" }, + { url = "https://files.pythonhosted.org/packages/b1/4e/60780e631d73b6b02bd7239f89c451a72970e5e7ec34f621eda55cd9a445/matplotlib-3.10.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:acc86dd6e0e695c095001a7fccff158c49e45e0758fdf5dcdbb0103318b59c9f", size = 8316869, upload-time = "2025-08-30T00:13:28.262Z" }, + { url = "https://files.pythonhosted.org/packages/f8/15/baa662374a579413210fc2115d40c503b7360a08e9cc254aa0d97d34b0c1/matplotlib-3.10.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e228cd2ffb8f88b7d0b29e37f68ca9aaf83e33821f24a5ccc4f082dd8396bc27", size = 8178240, upload-time = "2025-08-30T00:13:30.007Z" }, + { url = "https://files.pythonhosted.org/packages/c6/3f/3c38e78d2aafdb8829fcd0857d25aaf9e7dd2dfcf7ec742765b585774931/matplotlib-3.10.6-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:658bc91894adeab669cf4bb4a186d049948262987e80f0857216387d7435d833", size = 8711719, upload-time = "2025-08-30T00:13:31.72Z" }, + { url = "https://files.pythonhosted.org/packages/96/4b/2ec2bbf8cefaa53207cc56118d1fa8a0f9b80642713ea9390235d331ede4/matplotlib-3.10.6-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8913b7474f6dd83ac444c9459c91f7f0f2859e839f41d642691b104e0af056aa", size = 9541422, upload-time = "2025-08-30T00:13:33.611Z" }, + { url = "https://files.pythonhosted.org/packages/83/7d/40255e89b3ef11c7871020563b2dd85f6cb1b4eff17c0f62b6eb14c8fa80/matplotlib-3.10.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:091cea22e059b89f6d7d1a18e2c33a7376c26eee60e401d92a4d6726c4e12706", size = 9594068, upload-time = "2025-08-30T00:13:35.833Z" }, + { url = "https://files.pythonhosted.org/packages/f0/a9/0213748d69dc842537a113493e1c27daf9f96bd7cc316f933dc8ec4de985/matplotlib-3.10.6-cp313-cp313t-win_amd64.whl", hash = "sha256:491e25e02a23d7207629d942c666924a6b61e007a48177fdd231a0097b7f507e", size = 8200100, upload-time = "2025-08-30T00:13:37.668Z" }, + { url = "https://files.pythonhosted.org/packages/be/15/79f9988066ce40b8a6f1759a934ea0cde8dc4adc2262255ee1bc98de6ad0/matplotlib-3.10.6-cp313-cp313t-win_arm64.whl", hash = "sha256:3d80d60d4e54cda462e2cd9a086d85cd9f20943ead92f575ce86885a43a565d5", size = 8042142, upload-time = "2025-08-30T00:13:39.426Z" }, + { url = "https://files.pythonhosted.org/packages/12/bb/02c35a51484aae5f49bd29f091286e7af5f3f677a9736c58a92b3c78baeb/matplotlib-3.10.6-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f2d684c3204fa62421bbf770ddfebc6b50130f9cad65531eeba19236d73bb488", size = 8252296, upload-time = "2025-08-30T00:14:19.49Z" }, + { url = "https://files.pythonhosted.org/packages/7d/85/41701e3092005aee9a2445f5ee3904d9dbd4a7df7a45905ffef29b7ef098/matplotlib-3.10.6-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:6f4a69196e663a41d12a728fab8751177215357906436804217d6d9cf0d4d6cf", size = 8116749, upload-time = "2025-08-30T00:14:21.344Z" }, + { url = "https://files.pythonhosted.org/packages/16/53/8d8fa0ea32a8c8239e04d022f6c059ee5e1b77517769feccd50f1df43d6d/matplotlib-3.10.6-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d6ca6ef03dfd269f4ead566ec6f3fb9becf8dab146fb999022ed85ee9f6b3eb", size = 8693933, upload-time = "2025-08-30T00:14:22.942Z" }, ] [[package]] @@ -1435,69 +1697,70 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/99/5b/a36a337438a14116b16480db471ad061c36c3694df7c2084a0da7ba538b7/matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90", size = 8159 } +sdist = { url = "https://files.pythonhosted.org/packages/99/5b/a36a337438a14116b16480db471ad061c36c3694df7c2084a0da7ba538b7/matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90", size = 8159, upload-time = "2024-04-15T13:44:44.803Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8f/8e/9ad090d3553c280a8060fbf6e24dc1c0c29704ee7d1c372f0c174aa59285/matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca", size = 9899 }, + { url = "https://files.pythonhosted.org/packages/8f/8e/9ad090d3553c280a8060fbf6e24dc1c0c29704ee7d1c372f0c174aa59285/matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca", size = 9899, upload-time = "2024-04-15T13:44:43.265Z" }, ] [[package]] name = "mdurl" version = "0.1.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729 } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 }, + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, ] [[package]] name = "mistune" -version = "3.0.2" +version = "3.1.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ef/c8/f0173fe3bf85fd891aee2e7bcd8207dfe26c2c683d727c5a6cc3aec7b628/mistune-3.0.2.tar.gz", hash = "sha256:fc7f93ded930c92394ef2cb6f04a8aabab4117a91449e72dcc8dfa646a508be8", size = 90840 } +sdist = { url = "https://files.pythonhosted.org/packages/d7/02/a7fb8b21d4d55ac93cdcde9d3638da5dd0ebdd3a4fed76c7725e10b81cbe/mistune-3.1.4.tar.gz", hash = "sha256:b5a7f801d389f724ec702840c11d8fc48f2b33519102fc7ee739e8177b672164", size = 94588, upload-time = "2025-08-29T07:20:43.594Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f0/74/c95adcdf032956d9ef6c89a9b8a5152bf73915f8c633f3e3d88d06bd699c/mistune-3.0.2-py3-none-any.whl", hash = "sha256:71481854c30fdbc938963d3605b72501f5c10a9320ecd412c121c163a1c7d205", size = 47958 }, + { url = "https://files.pythonhosted.org/packages/7a/f0/8282d9641415e9e33df173516226b404d367a0fc55e1a60424a152913abc/mistune-3.1.4-py3-none-any.whl", hash = "sha256:93691da911e5d9d2e23bc54472892aff676df27a75274962ff9edc210364266d", size = 53481, upload-time = "2025-08-29T07:20:42.218Z" }, ] [[package]] name = "mpmath" version = "1.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106 } +sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106, upload-time = "2023-03-07T16:47:11.061Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198 }, + { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" }, ] [[package]] name = "multiprocess" -version = "0.70.17" +version = "0.70.18" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "dill" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e9/34/1acca6e18697017ad5c8b45279b59305d660ecf2fbed13e5f406f69890e4/multiprocess-0.70.17.tar.gz", hash = "sha256:4ae2f11a3416809ebc9a48abfc8b14ecce0652a0944731a1493a3c1ba44ff57a", size = 1785744 } +sdist = { url = "https://files.pythonhosted.org/packages/72/fd/2ae3826f5be24c6ed87266bc4e59c46ea5b059a103f3d7e7eb76a52aeecb/multiprocess-0.70.18.tar.gz", hash = "sha256:f9597128e6b3e67b23956da07cf3d2e5cba79e2f4e0fba8d7903636663ec6d0d", size = 1798503, upload-time = "2025-04-17T03:11:27.742Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f2/97/e57eaa8a4dc4036460d13162470eb0da520e6496a90b943529cf1ca40ebd/multiprocess-0.70.17-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7ddb24e5bcdb64e90ec5543a1f05a39463068b6d3b804aa3f2a4e16ec28562d6", size = 135007 }, - { url = "https://files.pythonhosted.org/packages/8f/0a/bb06ea45e5b400cd9944e05878fdbb9016ba78ffb9190c541eec9c8e8380/multiprocess-0.70.17-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d729f55198a3579f6879766a6d9b72b42d4b320c0dcb7844afb774d75b573c62", size = 135008 }, - { url = "https://files.pythonhosted.org/packages/20/e3/db48b10f0a25569c5c3a20288d82f9677cb312bccbd1da16cf8fb759649f/multiprocess-0.70.17-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c2c82d0375baed8d8dd0d8c38eb87c5ae9c471f8e384ad203a36f095ee860f67", size = 135012 }, - { url = "https://files.pythonhosted.org/packages/e7/a9/39cf856d03690af6fd570cf40331f1f79acdbb3132a9c35d2c5002f7f30b/multiprocess-0.70.17-py310-none-any.whl", hash = "sha256:38357ca266b51a2e22841b755d9a91e4bb7b937979a54d411677111716c32744", size = 134830 }, - { url = "https://files.pythonhosted.org/packages/b2/07/8cbb75d6cfbe8712d8f7f6a5615f083c6e710ab916b748fbb20373ddb142/multiprocess-0.70.17-py311-none-any.whl", hash = "sha256:2884701445d0177aec5bd5f6ee0df296773e4fb65b11903b94c613fb46cfb7d1", size = 144346 }, - { url = "https://files.pythonhosted.org/packages/a4/69/d3f343a61a2f86ef10ed7865a26beda7c71554136ce187b0384b1c2c9ca3/multiprocess-0.70.17-py312-none-any.whl", hash = "sha256:2818af14c52446b9617d1b0755fa70ca2f77c28b25ed97bdaa2c69a22c47b46c", size = 147990 }, - { url = "https://files.pythonhosted.org/packages/ae/d7/fd7a092fc0ab1845a1a97ca88e61b9b7cc2e9d6fcf0ed24e9480590c2336/multiprocess-0.70.17-py38-none-any.whl", hash = "sha256:1d52f068357acd1e5bbc670b273ef8f81d57863235d9fbf9314751886e141968", size = 132635 }, - { url = "https://files.pythonhosted.org/packages/f9/41/0618ac724b8a56254962c143759e04fa01c73b37aa69dd433f16643bd38b/multiprocess-0.70.17-py39-none-any.whl", hash = "sha256:c3feb874ba574fbccfb335980020c1ac631fbf2a3f7bee4e2042ede62558a021", size = 133359 }, + { url = "https://files.pythonhosted.org/packages/55/4d/9af0d1279c84618bcd35bf5fd7e371657358c7b0a523e54a9cffb87461f8/multiprocess-0.70.18-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:8b8940ae30139e04b076da6c5b83e9398585ebdf0f2ad3250673fef5b2ff06d6", size = 144695, upload-time = "2025-04-17T03:11:09.161Z" }, + { url = "https://files.pythonhosted.org/packages/17/bf/87323e79dd0562474fad3373c21c66bc6c3c9963b68eb2a209deb4c8575e/multiprocess-0.70.18-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0929ba95831adb938edbd5fb801ac45e705ecad9d100b3e653946b7716cb6bd3", size = 144742, upload-time = "2025-04-17T03:11:10.072Z" }, + { url = "https://files.pythonhosted.org/packages/dd/74/cb8c831e58dc6d5cf450b17c7db87f14294a1df52eb391da948b5e0a0b94/multiprocess-0.70.18-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4d77f8e4bfe6c6e2e661925bbf9aed4d5ade9a1c6502d5dfc10129b9d1141797", size = 144745, upload-time = "2025-04-17T03:11:11.453Z" }, + { url = "https://files.pythonhosted.org/packages/ba/d8/0cba6cf51a1a31f20471fbc823a716170c73012ddc4fb85d706630ed6e8f/multiprocess-0.70.18-py310-none-any.whl", hash = "sha256:60c194974c31784019c1f459d984e8f33ee48f10fcf42c309ba97b30d9bd53ea", size = 134948, upload-time = "2025-04-17T03:11:20.223Z" }, + { url = "https://files.pythonhosted.org/packages/4b/88/9039f2fed1012ef584751d4ceff9ab4a51e5ae264898f0b7cbf44340a859/multiprocess-0.70.18-py311-none-any.whl", hash = "sha256:5aa6eef98e691281b3ad923be2832bf1c55dd2c859acd73e5ec53a66aae06a1d", size = 144462, upload-time = "2025-04-17T03:11:21.657Z" }, + { url = "https://files.pythonhosted.org/packages/bf/b6/5f922792be93b82ec6b5f270bbb1ef031fd0622847070bbcf9da816502cc/multiprocess-0.70.18-py312-none-any.whl", hash = "sha256:9b78f8e5024b573730bfb654783a13800c2c0f2dfc0c25e70b40d184d64adaa2", size = 150287, upload-time = "2025-04-17T03:11:22.69Z" }, + { url = "https://files.pythonhosted.org/packages/ee/25/7d7e78e750bc1aecfaf0efbf826c69a791d2eeaf29cf20cba93ff4cced78/multiprocess-0.70.18-py313-none-any.whl", hash = "sha256:871743755f43ef57d7910a38433cfe41319e72be1bbd90b79c7a5ac523eb9334", size = 151917, upload-time = "2025-04-17T03:11:24.044Z" }, + { url = "https://files.pythonhosted.org/packages/3b/c3/ca84c19bd14cdfc21c388fdcebf08b86a7a470ebc9f5c3c084fc2dbc50f7/multiprocess-0.70.18-py38-none-any.whl", hash = "sha256:dbf705e52a154fe5e90fb17b38f02556169557c2dd8bb084f2e06c2784d8279b", size = 132636, upload-time = "2025-04-17T03:11:24.936Z" }, + { url = "https://files.pythonhosted.org/packages/6c/28/dd72947e59a6a8c856448a5e74da6201cb5502ddff644fbc790e4bd40b9a/multiprocess-0.70.18-py39-none-any.whl", hash = "sha256:e78ca805a72b1b810c690b6b4cc32579eba34f403094bbbae962b7b5bf9dfcb8", size = 133478, upload-time = "2025-04-17T03:11:26.253Z" }, ] [[package]] name = "natsort" version = "8.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e2/a9/a0c57aee75f77794adaf35322f8b6404cbd0f89ad45c87197a937764b7d0/natsort-8.4.0.tar.gz", hash = "sha256:45312c4a0e5507593da193dedd04abb1469253b601ecaf63445ad80f0a1ea581", size = 76575 } +sdist = { url = "https://files.pythonhosted.org/packages/e2/a9/a0c57aee75f77794adaf35322f8b6404cbd0f89ad45c87197a937764b7d0/natsort-8.4.0.tar.gz", hash = "sha256:45312c4a0e5507593da193dedd04abb1469253b601ecaf63445ad80f0a1ea581", size = 76575, upload-time = "2023-06-20T04:17:19.925Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/82/7a9d0550484a62c6da82858ee9419f3dd1ccc9aa1c26a1e43da3ecd20b0d/natsort-8.4.0-py3-none-any.whl", hash = "sha256:4732914fb471f56b5cce04d7bae6f164a592c7712e1c85f9ef585e197299521c", size = 38268 }, + { url = "https://files.pythonhosted.org/packages/ef/82/7a9d0550484a62c6da82858ee9419f3dd1ccc9aa1c26a1e43da3ecd20b0d/natsort-8.4.0-py3-none-any.whl", hash = "sha256:4732914fb471f56b5cce04d7bae6f164a592c7712e1c85f9ef585e197299521c", size = 38268, upload-time = "2023-06-20T04:17:17.522Z" }, ] [[package]] name = "nbclient" -version = "0.10.1" +version = "0.10.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jupyter-client" }, @@ -1505,18 +1768,18 @@ dependencies = [ { name = "nbformat" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/06/db/25929926860ba8a3f6123d2d0a235e558e0e4be7b46e9db063a7dfefa0a2/nbclient-0.10.1.tar.gz", hash = "sha256:3e93e348ab27e712acd46fccd809139e356eb9a31aab641d1a7991a6eb4e6f68", size = 62273 } +sdist = { url = "https://files.pythonhosted.org/packages/87/66/7ffd18d58eae90d5721f9f39212327695b749e23ad44b3881744eaf4d9e8/nbclient-0.10.2.tar.gz", hash = "sha256:90b7fc6b810630db87a6d0c2250b1f0ab4cf4d3c27a299b0cde78a4ed3fd9193", size = 62424, upload-time = "2024-12-19T10:32:27.164Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/26/1a/ed6d1299b1a00c1af4a033fdee565f533926d819e084caf0d2832f6f87c6/nbclient-0.10.1-py3-none-any.whl", hash = "sha256:949019b9240d66897e442888cfb618f69ef23dc71c01cb5fced8499c2cfc084d", size = 25344 }, + { url = "https://files.pythonhosted.org/packages/34/6d/e7fa07f03a4a7b221d94b4d586edb754a9b0dc3c9e2c93353e9fa4e0d117/nbclient-0.10.2-py3-none-any.whl", hash = "sha256:4ffee11e788b4a27fabeb7955547e4318a5298f34342a4bfd01f2e1faaeadc3d", size = 25434, upload-time = "2024-12-19T10:32:24.139Z" }, ] [[package]] name = "nbconvert" -version = "7.16.4" +version = "7.16.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "beautifulsoup4" }, - { name = "bleach" }, + { name = "bleach", extra = ["css"] }, { name = "defusedxml" }, { name = "jinja2" }, { name = "jupyter-core" }, @@ -1528,12 +1791,11 @@ dependencies = [ { name = "packaging" }, { name = "pandocfilters" }, { name = "pygments" }, - { name = "tinycss2" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/af/e8/ba521a033b21132008e520c28ceb818f9f092da5f0261e94e509401b29f9/nbconvert-7.16.4.tar.gz", hash = "sha256:86ca91ba266b0a448dc96fa6c5b9d98affabde2867b363258703536807f9f7f4", size = 854422 } +sdist = { url = "https://files.pythonhosted.org/packages/a3/59/f28e15fc47ffb73af68a8d9b47367a8630d76e97ae85ad18271b9db96fdf/nbconvert-7.16.6.tar.gz", hash = "sha256:576a7e37c6480da7b8465eefa66c17844243816ce1ccc372633c6b71c3c0f582", size = 857715, upload-time = "2025-01-28T09:29:14.724Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b8/bb/bb5b6a515d1584aa2fd89965b11db6632e4bdc69495a52374bcc36e56cfa/nbconvert-7.16.4-py3-none-any.whl", hash = "sha256:05873c620fe520b6322bf8a5ad562692343fe3452abda5765c7a34b7d1aa3eb3", size = 257388 }, + { url = "https://files.pythonhosted.org/packages/cc/9a/cd673b2f773a12c992f41309ef81b99da1690426bd2f96957a7ade0d3ed7/nbconvert-7.16.6-py3-none-any.whl", hash = "sha256:1375a7b67e0c2883678c48e506dc320febb57685e5ee67faa51b18a90f3a712b", size = 258525, upload-time = "2025-01-28T09:29:12.551Z" }, ] [[package]] @@ -1546,27 +1808,36 @@ dependencies = [ { name = "jupyter-core" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6d/fd/91545e604bc3dad7dca9ed03284086039b294c6b3d75c0d2fa45f9e9caf3/nbformat-5.10.4.tar.gz", hash = "sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a", size = 142749 } +sdist = { url = "https://files.pythonhosted.org/packages/6d/fd/91545e604bc3dad7dca9ed03284086039b294c6b3d75c0d2fa45f9e9caf3/nbformat-5.10.4.tar.gz", hash = "sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a", size = 142749, upload-time = "2024-04-04T11:20:37.371Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl", hash = "sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b", size = 78454 }, + { url = "https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl", hash = "sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b", size = 78454, upload-time = "2024-04-04T11:20:34.895Z" }, ] [[package]] name = "nest-asyncio" version = "1.6.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/83/f8/51569ac65d696c8ecbee95938f89d4abf00f47d58d48f6fbabfe8f0baefe/nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe", size = 7418 } +sdist = { url = "https://files.pythonhosted.org/packages/83/f8/51569ac65d696c8ecbee95938f89d4abf00f47d58d48f6fbabfe8f0baefe/nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe", size = 7418, upload-time = "2024-01-21T14:25:19.227Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c", size = 5195 }, + { url = "https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c", size = 5195, upload-time = "2024-01-21T14:25:17.223Z" }, ] [[package]] name = "networkx" -version = "3.2.1" +version = "3.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c4/80/a84676339aaae2f1cfdf9f418701dd634aef9cc76f708ef55c36ff39c3ca/networkx-3.2.1.tar.gz", hash = "sha256:9f1bb5cf3409bf324e0a722c20bdb4c20ee39bf1c30ce8ae499c8502b0b5e0c6", size = 2073928 } +sdist = { url = "https://files.pythonhosted.org/packages/6c/4f/ccdb8ad3a38e583f214547fd2f7ff1fc160c43a75af88e6aec213404b96a/networkx-3.5.tar.gz", hash = "sha256:d4c6f9cf81f52d69230866796b82afbccdec3db7ae4fbd1b65ea750feed50037", size = 2471065, upload-time = "2025-05-29T11:35:07.804Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d5/f0/8fbc882ca80cf077f1b246c0e3c3465f7f415439bdea6b899f6b19f61f70/networkx-3.2.1-py3-none-any.whl", hash = "sha256:f18c69adc97877c42332c170849c96cefa91881c99a7cb3e95b7c659ebdc1ec2", size = 1647772 }, + { url = "https://files.pythonhosted.org/packages/eb/8d/776adee7bbf76365fdd7f2552710282c79a4ead5d2a46408c9043a2b70ba/networkx-3.5-py3-none-any.whl", hash = "sha256:0030d386a9a06dee3565298b4a734b68589749a544acbb6c412dc9e2489ec6ec", size = 2034406, upload-time = "2025-05-29T11:35:04.961Z" }, +] + +[[package]] +name = "nodeenv" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437, upload-time = "2024-06-04T18:44:11.171Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" }, ] [[package]] @@ -1576,68 +1847,128 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jupyter-server" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/54/d2/92fa3243712b9a3e8bafaf60aac366da1cada3639ca767ff4b5b3654ec28/notebook_shim-0.2.4.tar.gz", hash = "sha256:b4b2cfa1b65d98307ca24361f5b30fe785b53c3fd07b7a47e89acb5e6ac638cb", size = 13167 } +sdist = { url = "https://files.pythonhosted.org/packages/54/d2/92fa3243712b9a3e8bafaf60aac366da1cada3639ca767ff4b5b3654ec28/notebook_shim-0.2.4.tar.gz", hash = "sha256:b4b2cfa1b65d98307ca24361f5b30fe785b53c3fd07b7a47e89acb5e6ac638cb", size = 13167, upload-time = "2024-02-14T23:35:18.353Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl", hash = "sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef", size = 13307 }, + { url = "https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl", hash = "sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef", size = 13307, upload-time = "2024-02-14T23:35:16.286Z" }, ] [[package]] name = "numba" -version = "0.60.0" +version = "0.61.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "llvmlite" }, { name = "numpy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3c/93/2849300a9184775ba274aba6f82f303343669b0592b7bb0849ea713dabb0/numba-0.60.0.tar.gz", hash = "sha256:5df6158e5584eece5fc83294b949fd30b9f1125df7708862205217e068aabf16", size = 2702171 } +sdist = { url = "https://files.pythonhosted.org/packages/1c/a0/e21f57604304aa03ebb8e098429222722ad99176a4f979d34af1d1ee80da/numba-0.61.2.tar.gz", hash = "sha256:8750ee147940a6637b80ecf7f95062185ad8726c8c28a2295b8ec1160a196f7d", size = 2820615, upload-time = "2025-04-09T02:58:07.659Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f7/cf/baa13a7e3556d73d9e38021e6d6aa4aeb30d8b94545aa8b70d0f24a1ccc4/numba-0.60.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5d761de835cd38fb400d2c26bb103a2726f548dc30368853121d66201672e651", size = 2647627 }, - { url = "https://files.pythonhosted.org/packages/ac/ba/4b57fa498564457c3cc9fc9e570a6b08e6086c74220f24baaf04e54b995f/numba-0.60.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:159e618ef213fba758837f9837fb402bbe65326e60ba0633dbe6c7f274d42c1b", size = 2650322 }, - { url = "https://files.pythonhosted.org/packages/28/98/7ea97ee75870a54f938a8c70f7e0be4495ba5349c5f9db09d467c4a5d5b7/numba-0.60.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1527dc578b95c7c4ff248792ec33d097ba6bef9eda466c948b68dfc995c25781", size = 3407390 }, - { url = "https://files.pythonhosted.org/packages/79/58/cb4ac5b8f7ec64200460aef1fed88258fb872ceef504ab1f989d2ff0f684/numba-0.60.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fe0b28abb8d70f8160798f4de9d486143200f34458d34c4a214114e445d7124e", size = 3699694 }, - { url = "https://files.pythonhosted.org/packages/1c/b0/c61a93ca947d12233ff45de506ddbf52af3f752066a0b8be4d27426e16da/numba-0.60.0-cp310-cp310-win_amd64.whl", hash = "sha256:19407ced081d7e2e4b8d8c36aa57b7452e0283871c296e12d798852bc7d7f198", size = 2687030 }, - { url = "https://files.pythonhosted.org/packages/98/ad/df18d492a8f00d29a30db307904b9b296e37507034eedb523876f3a2e13e/numba-0.60.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a17b70fc9e380ee29c42717e8cc0bfaa5556c416d94f9aa96ba13acb41bdece8", size = 2647254 }, - { url = "https://files.pythonhosted.org/packages/9a/51/a4dc2c01ce7a850b8e56ff6d5381d047a5daea83d12bad08aa071d34b2ee/numba-0.60.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3fb02b344a2a80efa6f677aa5c40cd5dd452e1b35f8d1c2af0dfd9ada9978e4b", size = 2649970 }, - { url = "https://files.pythonhosted.org/packages/f9/4c/8889ac94c0b33dca80bed11564b8c6d9ea14d7f094e674c58e5c5b05859b/numba-0.60.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5f4fde652ea604ea3c86508a3fb31556a6157b2c76c8b51b1d45eb40c8598703", size = 3412492 }, - { url = "https://files.pythonhosted.org/packages/57/03/2b4245b05b71c0cee667e6a0b51606dfa7f4157c9093d71c6b208385a611/numba-0.60.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4142d7ac0210cc86432b818338a2bc368dc773a2f5cf1e32ff7c5b378bd63ee8", size = 3705018 }, - { url = "https://files.pythonhosted.org/packages/79/89/2d924ca60dbf949f18a6fec223a2445f5f428d9a5f97a6b29c2122319015/numba-0.60.0-cp311-cp311-win_amd64.whl", hash = "sha256:cac02c041e9b5bc8cf8f2034ff6f0dbafccd1ae9590dc146b3a02a45e53af4e2", size = 2686920 }, - { url = "https://files.pythonhosted.org/packages/eb/5c/b5ec752c475e78a6c3676b67c514220dbde2725896bbb0b6ec6ea54b2738/numba-0.60.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d7da4098db31182fc5ffe4bc42c6f24cd7d1cb8a14b59fd755bfee32e34b8404", size = 2647866 }, - { url = "https://files.pythonhosted.org/packages/65/42/39559664b2e7c15689a638c2a38b3b74c6e69a04e2b3019b9f7742479188/numba-0.60.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:38d6ea4c1f56417076ecf8fc327c831ae793282e0ff51080c5094cb726507b1c", size = 2650208 }, - { url = "https://files.pythonhosted.org/packages/67/88/c4459ccc05674ef02119abf2888ccd3e2fed12a323f52255f4982fc95876/numba-0.60.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:62908d29fb6a3229c242e981ca27e32a6e606cc253fc9e8faeb0e48760de241e", size = 3466946 }, - { url = "https://files.pythonhosted.org/packages/8b/41/ac11cf33524def12aa5bd698226ae196a1185831c05ed29dc0c56eaa308b/numba-0.60.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0ebaa91538e996f708f1ab30ef4d3ddc344b64b5227b67a57aa74f401bb68b9d", size = 3761463 }, - { url = "https://files.pythonhosted.org/packages/ca/bd/0fe29fcd1b6a8de479a4ed25c6e56470e467e3611c079d55869ceef2b6d1/numba-0.60.0-cp312-cp312-win_amd64.whl", hash = "sha256:f75262e8fe7fa96db1dca93d53a194a38c46da28b112b8a4aca168f0df860347", size = 2707588 }, + { url = "https://files.pythonhosted.org/packages/3f/97/c99d1056aed767503c228f7099dc11c402906b42a4757fec2819329abb98/numba-0.61.2-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:efd3db391df53aaa5cfbee189b6c910a5b471488749fd6606c3f33fc984c2ae2", size = 2775825, upload-time = "2025-04-09T02:57:43.442Z" }, + { url = "https://files.pythonhosted.org/packages/95/9e/63c549f37136e892f006260c3e2613d09d5120672378191f2dc387ba65a2/numba-0.61.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:49c980e4171948ffebf6b9a2520ea81feed113c1f4890747ba7f59e74be84b1b", size = 2778695, upload-time = "2025-04-09T02:57:44.968Z" }, + { url = "https://files.pythonhosted.org/packages/97/c8/8740616c8436c86c1b9a62e72cb891177d2c34c2d24ddcde4c390371bf4c/numba-0.61.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3945615cd73c2c7eba2a85ccc9c1730c21cd3958bfcf5a44302abae0fb07bb60", size = 3829227, upload-time = "2025-04-09T02:57:46.63Z" }, + { url = "https://files.pythonhosted.org/packages/fc/06/66e99ae06507c31d15ff3ecd1f108f2f59e18b6e08662cd5f8a5853fbd18/numba-0.61.2-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbfdf4eca202cebade0b7d43896978e146f39398909a42941c9303f82f403a18", size = 3523422, upload-time = "2025-04-09T02:57:48.222Z" }, + { url = "https://files.pythonhosted.org/packages/0f/a4/2b309a6a9f6d4d8cfba583401c7c2f9ff887adb5d54d8e2e130274c0973f/numba-0.61.2-cp311-cp311-win_amd64.whl", hash = "sha256:76bcec9f46259cedf888041b9886e257ae101c6268261b19fda8cfbc52bec9d1", size = 2831505, upload-time = "2025-04-09T02:57:50.108Z" }, + { url = "https://files.pythonhosted.org/packages/b4/a0/c6b7b9c615cfa3b98c4c63f4316e3f6b3bbe2387740277006551784218cd/numba-0.61.2-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:34fba9406078bac7ab052efbf0d13939426c753ad72946baaa5bf9ae0ebb8dd2", size = 2776626, upload-time = "2025-04-09T02:57:51.857Z" }, + { url = "https://files.pythonhosted.org/packages/92/4a/fe4e3c2ecad72d88f5f8cd04e7f7cff49e718398a2fac02d2947480a00ca/numba-0.61.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4ddce10009bc097b080fc96876d14c051cc0c7679e99de3e0af59014dab7dfe8", size = 2779287, upload-time = "2025-04-09T02:57:53.658Z" }, + { url = "https://files.pythonhosted.org/packages/9a/2d/e518df036feab381c23a624dac47f8445ac55686ec7f11083655eb707da3/numba-0.61.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5b1bb509d01f23d70325d3a5a0e237cbc9544dd50e50588bc581ba860c213546", size = 3885928, upload-time = "2025-04-09T02:57:55.206Z" }, + { url = "https://files.pythonhosted.org/packages/10/0f/23cced68ead67b75d77cfcca3df4991d1855c897ee0ff3fe25a56ed82108/numba-0.61.2-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:48a53a3de8f8793526cbe330f2a39fe9a6638efcbf11bd63f3d2f9757ae345cd", size = 3577115, upload-time = "2025-04-09T02:57:56.818Z" }, + { url = "https://files.pythonhosted.org/packages/68/1d/ddb3e704c5a8fb90142bf9dc195c27db02a08a99f037395503bfbc1d14b3/numba-0.61.2-cp312-cp312-win_amd64.whl", hash = "sha256:97cf4f12c728cf77c9c1d7c23707e4d8fb4632b46275f8f3397de33e5877af18", size = 2831929, upload-time = "2025-04-09T02:57:58.45Z" }, + { url = "https://files.pythonhosted.org/packages/0b/f3/0fe4c1b1f2569e8a18ad90c159298d862f96c3964392a20d74fc628aee44/numba-0.61.2-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:3a10a8fc9afac40b1eac55717cece1b8b1ac0b946f5065c89e00bde646b5b154", size = 2771785, upload-time = "2025-04-09T02:57:59.96Z" }, + { url = "https://files.pythonhosted.org/packages/e9/71/91b277d712e46bd5059f8a5866862ed1116091a7cb03bd2704ba8ebe015f/numba-0.61.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7d3bcada3c9afba3bed413fba45845f2fb9cd0d2b27dd58a1be90257e293d140", size = 2773289, upload-time = "2025-04-09T02:58:01.435Z" }, + { url = "https://files.pythonhosted.org/packages/0d/e0/5ea04e7ad2c39288c0f0f9e8d47638ad70f28e275d092733b5817cf243c9/numba-0.61.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bdbca73ad81fa196bd53dc12e3aaf1564ae036e0c125f237c7644fe64a4928ab", size = 3893918, upload-time = "2025-04-09T02:58:02.933Z" }, + { url = "https://files.pythonhosted.org/packages/17/58/064f4dcb7d7e9412f16ecf80ed753f92297e39f399c905389688cf950b81/numba-0.61.2-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:5f154aaea625fb32cfbe3b80c5456d514d416fcdf79733dd69c0df3a11348e9e", size = 3584056, upload-time = "2025-04-09T02:58:04.538Z" }, + { url = "https://files.pythonhosted.org/packages/af/a4/6d3a0f2d3989e62a18749e1e9913d5fa4910bbb3e3311a035baea6caf26d/numba-0.61.2-cp313-cp313-win_amd64.whl", hash = "sha256:59321215e2e0ac5fa928a8020ab00b8e57cda8a97384963ac0dfa4d4e6aa54e7", size = 2831846, upload-time = "2025-04-09T02:58:06.125Z" }, +] + +[[package]] +name = "numcodecs" +version = "0.16.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a1/1d/837d946aab385abe1e472ec08a6816d84b00f4ceeae5445eb8f25c5c6ca9/numcodecs-0.16.2.tar.gz", hash = "sha256:9922dae0c3b01b5bed3b4bae239f4787e891daa3262c27971298669d029d10e9", size = 6271668, upload-time = "2025-08-13T16:09:26.125Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/19/38b3fbb2335e31fdd253e1de0531b32e8245b86a7b9d46c474fa6d2cb5c5/numcodecs-0.16.2-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:4c1f1357896cfc5451157fd90a2858aa0f6a66409f91f3016d257b76c4c244c1", size = 1629357, upload-time = "2025-08-13T16:09:00.425Z" }, + { url = "https://files.pythonhosted.org/packages/3d/f8/ba257b7627477f5650aa8274e7a6f9a72c4d51c1e7ac968b14b65d872c76/numcodecs-0.16.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d88aa4f82bb8fe3fa2e9c19fd44b6c268acec6fc7bcff59c92e169830d09531a", size = 1158894, upload-time = "2025-08-13T16:09:02.285Z" }, + { url = "https://files.pythonhosted.org/packages/e3/31/0c90266a9ba048223656d552c5b40ea22d788be77797e8a0db9d698a3847/numcodecs-0.16.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:276f657ec4ffef9e2cc344b732b8906fe8612c3b9484504830ccdc7a2dd0715a", size = 8285212, upload-time = "2025-08-13T16:09:03.716Z" }, + { url = "https://files.pythonhosted.org/packages/01/24/7889b678c0b7e3f605e1ec2fe1ddee0f48920098fecb0cadd5bd66483044/numcodecs-0.16.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1b7d8174e14c66191e0e1a4a44dd264bd776fb96b1ce3adc0216154f34b755c", size = 8811508, upload-time = "2025-08-13T16:09:05.68Z" }, + { url = "https://files.pythonhosted.org/packages/87/26/23b474b188a8e005bbd5e516e3415ec9f2b59fbf1f36636e5cfc14f59c54/numcodecs-0.16.2-cp311-cp311-win_amd64.whl", hash = "sha256:559163a7d97ec8aef1654e47c6e97f88dcc4c38a975338bf1bfb214d3c8d70f9", size = 804099, upload-time = "2025-08-13T16:09:07.589Z" }, + { url = "https://files.pythonhosted.org/packages/03/c3/5470273d6d5c986521140ccec6476664ea4e03c0cfc51b370fb03368bb41/numcodecs-0.16.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:30f04c2b7bb802133866e7fb554d47943864f977dfe8a95c814eb801c797df3c", size = 1668488, upload-time = "2025-08-13T16:09:08.942Z" }, + { url = "https://files.pythonhosted.org/packages/db/bf/cc1aaea87371097d6b5236ec44f8eb96387b52204b4e671fac716e5de325/numcodecs-0.16.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8ee0b2776cf47b7702ba0ccc0b6afaad28afbf8d5bb7b9a5274b5f08ecc651b2", size = 1155083, upload-time = "2025-08-13T16:09:10.641Z" }, + { url = "https://files.pythonhosted.org/packages/6b/c1/ba5ab0cf4c4d737635d20d8b72a61c26f8f99c0529606dfbfa3e5d3a4221/numcodecs-0.16.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c8e94f0e90aaf4d01b2e26476d3b081c2cf8c17036af45e04e735de9c0cf64f", size = 8260568, upload-time = "2025-08-13T16:09:12.063Z" }, + { url = "https://files.pythonhosted.org/packages/3b/64/7177bf632520705893683fa4ca202ed540450bf971c0453ad1351baa2007/numcodecs-0.16.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b565b16366749011e290343617571db861b2b2e58b038697afde6d02f537c91", size = 8792262, upload-time = "2025-08-13T16:09:14.058Z" }, + { url = "https://files.pythonhosted.org/packages/10/90/df01799f4c1bb8618b842582d10d362829e980c4d5eb9701c1aeadf5c4e3/numcodecs-0.16.2-cp312-cp312-win_amd64.whl", hash = "sha256:e4cfdde4e99bf47580f4eb3a876630c73ba14e4a1380fec5959ac727e22ce0d2", size = 803444, upload-time = "2025-08-13T16:09:16.09Z" }, + { url = "https://files.pythonhosted.org/packages/b6/e3/f61c422259a4b6c8c2496d284f85ed17f8686b3a53feb797d3bd66ef499c/numcodecs-0.16.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0f965ccb2f6d215ffd2e3239ec02e33139d7ce311ff49704d340704b81dda653", size = 1664476, upload-time = "2025-08-13T16:09:17.327Z" }, + { url = "https://files.pythonhosted.org/packages/b9/a7/fa4d66b86e277643d135af263efc0dd1f98cf1228d3b4554b843c0c1a09b/numcodecs-0.16.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b4bc110b73d59de7f46310c680f075f9007ead915174c895368274c646c9ea74", size = 1148718, upload-time = "2025-08-13T16:09:19.075Z" }, + { url = "https://files.pythonhosted.org/packages/17/43/9656a6b0ed7250ca3a5c126a6077a29398c3dca9176224dba4634847a4a4/numcodecs-0.16.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51615cf2811343a8a3fa42953cb4120ac7187875a161260444f53ada5710063e", size = 8205330, upload-time = "2025-08-13T16:09:20.904Z" }, + { url = "https://files.pythonhosted.org/packages/55/7f/0ab8db32ef9b51c60f7b759c2b155e1edcb08febb508c22a9d04b19ec735/numcodecs-0.16.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a18ced1ecbdd0e9ee716820dbb3a094c896eed8005273bbcab9980bdac270ae", size = 8750769, upload-time = "2025-08-13T16:09:22.516Z" }, + { url = "https://files.pythonhosted.org/packages/f0/0c/25f96c7969bdbfcc1427dc82eba92f2ef4df84c63369c95ab99af6404c23/numcodecs-0.16.2-cp313-cp313-win_amd64.whl", hash = "sha256:f640ed8406e1eb5806787a3e5be223d455b75c99eb2088a290947ed6dbd77e8e", size = 800281, upload-time = "2025-08-13T16:09:24.691Z" }, +] + +[package.optional-dependencies] +crc32c = [ + { name = "crc32c" }, ] [[package]] name = "numpy" -version = "1.26.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/65/6e/09db70a523a96d25e115e71cc56a6f9031e7b8cd166c1ac8438307c14058/numpy-1.26.4.tar.gz", hash = "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010", size = 15786129 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/94/ace0fdea5241a27d13543ee117cbc65868e82213fb31a8eb7fe9ff23f313/numpy-1.26.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0", size = 20631468 }, - { url = "https://files.pythonhosted.org/packages/20/f7/b24208eba89f9d1b58c1668bc6c8c4fd472b20c45573cb767f59d49fb0f6/numpy-1.26.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a", size = 13966411 }, - { url = "https://files.pythonhosted.org/packages/fc/a5/4beee6488160798683eed5bdb7eead455892c3b4e1f78d79d8d3f3b084ac/numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4", size = 14219016 }, - { url = "https://files.pythonhosted.org/packages/4b/d7/ecf66c1cd12dc28b4040b15ab4d17b773b87fa9d29ca16125de01adb36cd/numpy-1.26.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f", size = 18240889 }, - { url = "https://files.pythonhosted.org/packages/24/03/6f229fe3187546435c4f6f89f6d26c129d4f5bed40552899fcf1f0bf9e50/numpy-1.26.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a", size = 13876746 }, - { url = "https://files.pythonhosted.org/packages/39/fe/39ada9b094f01f5a35486577c848fe274e374bbf8d8f472e1423a0bbd26d/numpy-1.26.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2", size = 18078620 }, - { url = "https://files.pythonhosted.org/packages/d5/ef/6ad11d51197aad206a9ad2286dc1aac6a378059e06e8cf22cd08ed4f20dc/numpy-1.26.4-cp310-cp310-win32.whl", hash = "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07", size = 5972659 }, - { url = "https://files.pythonhosted.org/packages/19/77/538f202862b9183f54108557bfda67e17603fc560c384559e769321c9d92/numpy-1.26.4-cp310-cp310-win_amd64.whl", hash = "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5", size = 15808905 }, - { url = "https://files.pythonhosted.org/packages/11/57/baae43d14fe163fa0e4c47f307b6b2511ab8d7d30177c491960504252053/numpy-1.26.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71", size = 20630554 }, - { url = "https://files.pythonhosted.org/packages/1a/2e/151484f49fd03944c4a3ad9c418ed193cfd02724e138ac8a9505d056c582/numpy-1.26.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef", size = 13997127 }, - { url = "https://files.pythonhosted.org/packages/79/ae/7e5b85136806f9dadf4878bf73cf223fe5c2636818ba3ab1c585d0403164/numpy-1.26.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e", size = 14222994 }, - { url = "https://files.pythonhosted.org/packages/3a/d0/edc009c27b406c4f9cbc79274d6e46d634d139075492ad055e3d68445925/numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5", size = 18252005 }, - { url = "https://files.pythonhosted.org/packages/09/bf/2b1aaf8f525f2923ff6cfcf134ae5e750e279ac65ebf386c75a0cf6da06a/numpy-1.26.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a", size = 13885297 }, - { url = "https://files.pythonhosted.org/packages/df/a0/4e0f14d847cfc2a633a1c8621d00724f3206cfeddeb66d35698c4e2cf3d2/numpy-1.26.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a", size = 18093567 }, - { url = "https://files.pythonhosted.org/packages/d2/b7/a734c733286e10a7f1a8ad1ae8c90f2d33bf604a96548e0a4a3a6739b468/numpy-1.26.4-cp311-cp311-win32.whl", hash = "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20", size = 5968812 }, - { url = "https://files.pythonhosted.org/packages/3f/6b/5610004206cf7f8e7ad91c5a85a8c71b2f2f8051a0c0c4d5916b76d6cbb2/numpy-1.26.4-cp311-cp311-win_amd64.whl", hash = "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2", size = 15811913 }, - { url = "https://files.pythonhosted.org/packages/95/12/8f2020a8e8b8383ac0177dc9570aad031a3beb12e38847f7129bacd96228/numpy-1.26.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218", size = 20335901 }, - { url = "https://files.pythonhosted.org/packages/75/5b/ca6c8bd14007e5ca171c7c03102d17b4f4e0ceb53957e8c44343a9546dcc/numpy-1.26.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b", size = 13685868 }, - { url = "https://files.pythonhosted.org/packages/79/f8/97f10e6755e2a7d027ca783f63044d5b1bc1ae7acb12afe6a9b4286eac17/numpy-1.26.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b", size = 13925109 }, - { url = "https://files.pythonhosted.org/packages/0f/50/de23fde84e45f5c4fda2488c759b69990fd4512387a8632860f3ac9cd225/numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed", size = 17950613 }, - { url = "https://files.pythonhosted.org/packages/4c/0c/9c603826b6465e82591e05ca230dfc13376da512b25ccd0894709b054ed0/numpy-1.26.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a", size = 13572172 }, - { url = "https://files.pythonhosted.org/packages/76/8c/2ba3902e1a0fc1c74962ea9bb33a534bb05984ad7ff9515bf8d07527cadd/numpy-1.26.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0", size = 17786643 }, - { url = "https://files.pythonhosted.org/packages/28/4a/46d9e65106879492374999e76eb85f87b15328e06bd1550668f79f7b18c6/numpy-1.26.4-cp312-cp312-win32.whl", hash = "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110", size = 5677803 }, - { url = "https://files.pythonhosted.org/packages/16/2e/86f24451c2d530c88daf997cb8d6ac622c1d40d19f5a031ed68a4b73a374/numpy-1.26.4-cp312-cp312-win_amd64.whl", hash = "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818", size = 15517754 }, +version = "2.2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/da/a8/4f83e2aa666a9fbf56d6118faaaf5f1974d456b1823fda0a176eff722839/numpy-2.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f9f1adb22318e121c5c69a09142811a201ef17ab257a1e66ca3025065b7f53ae", size = 21176963, upload-time = "2025-05-17T21:31:19.36Z" }, + { url = "https://files.pythonhosted.org/packages/b3/2b/64e1affc7972decb74c9e29e5649fac940514910960ba25cd9af4488b66c/numpy-2.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c820a93b0255bc360f53eca31a0e676fd1101f673dda8da93454a12e23fc5f7a", size = 14406743, upload-time = "2025-05-17T21:31:41.087Z" }, + { url = "https://files.pythonhosted.org/packages/4a/9f/0121e375000b5e50ffdd8b25bf78d8e1a5aa4cca3f185d41265198c7b834/numpy-2.2.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3d70692235e759f260c3d837193090014aebdf026dfd167834bcba43e30c2a42", size = 5352616, upload-time = "2025-05-17T21:31:50.072Z" }, + { url = "https://files.pythonhosted.org/packages/31/0d/b48c405c91693635fbe2dcd7bc84a33a602add5f63286e024d3b6741411c/numpy-2.2.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:481b49095335f8eed42e39e8041327c05b0f6f4780488f61286ed3c01368d491", size = 6889579, upload-time = "2025-05-17T21:32:01.712Z" }, + { url = "https://files.pythonhosted.org/packages/52/b8/7f0554d49b565d0171eab6e99001846882000883998e7b7d9f0d98b1f934/numpy-2.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b64d8d4d17135e00c8e346e0a738deb17e754230d7e0810ac5012750bbd85a5a", size = 14312005, upload-time = "2025-05-17T21:32:23.332Z" }, + { url = "https://files.pythonhosted.org/packages/b3/dd/2238b898e51bd6d389b7389ffb20d7f4c10066d80351187ec8e303a5a475/numpy-2.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba10f8411898fc418a521833e014a77d3ca01c15b0c6cdcce6a0d2897e6dbbdf", size = 16821570, upload-time = "2025-05-17T21:32:47.991Z" }, + { url = "https://files.pythonhosted.org/packages/83/6c/44d0325722cf644f191042bf47eedad61c1e6df2432ed65cbe28509d404e/numpy-2.2.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bd48227a919f1bafbdda0583705e547892342c26fb127219d60a5c36882609d1", size = 15818548, upload-time = "2025-05-17T21:33:11.728Z" }, + { url = "https://files.pythonhosted.org/packages/ae/9d/81e8216030ce66be25279098789b665d49ff19eef08bfa8cb96d4957f422/numpy-2.2.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9551a499bf125c1d4f9e250377c1ee2eddd02e01eac6644c080162c0c51778ab", size = 18620521, upload-time = "2025-05-17T21:33:39.139Z" }, + { url = "https://files.pythonhosted.org/packages/6a/fd/e19617b9530b031db51b0926eed5345ce8ddc669bb3bc0044b23e275ebe8/numpy-2.2.6-cp311-cp311-win32.whl", hash = "sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47", size = 6525866, upload-time = "2025-05-17T21:33:50.273Z" }, + { url = "https://files.pythonhosted.org/packages/31/0a/f354fb7176b81747d870f7991dc763e157a934c717b67b58456bc63da3df/numpy-2.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303", size = 12907455, upload-time = "2025-05-17T21:34:09.135Z" }, + { url = "https://files.pythonhosted.org/packages/82/5d/c00588b6cf18e1da539b45d3598d3557084990dcc4331960c15ee776ee41/numpy-2.2.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41c5a21f4a04fa86436124d388f6ed60a9343a6f767fced1a8a71c3fbca038ff", size = 20875348, upload-time = "2025-05-17T21:34:39.648Z" }, + { url = "https://files.pythonhosted.org/packages/66/ee/560deadcdde6c2f90200450d5938f63a34b37e27ebff162810f716f6a230/numpy-2.2.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de749064336d37e340f640b05f24e9e3dd678c57318c7289d222a8a2f543e90c", size = 14119362, upload-time = "2025-05-17T21:35:01.241Z" }, + { url = "https://files.pythonhosted.org/packages/3c/65/4baa99f1c53b30adf0acd9a5519078871ddde8d2339dc5a7fde80d9d87da/numpy-2.2.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:894b3a42502226a1cac872f840030665f33326fc3dac8e57c607905773cdcde3", size = 5084103, upload-time = "2025-05-17T21:35:10.622Z" }, + { url = "https://files.pythonhosted.org/packages/cc/89/e5a34c071a0570cc40c9a54eb472d113eea6d002e9ae12bb3a8407fb912e/numpy-2.2.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:71594f7c51a18e728451bb50cc60a3ce4e6538822731b2933209a1f3614e9282", size = 6625382, upload-time = "2025-05-17T21:35:21.414Z" }, + { url = "https://files.pythonhosted.org/packages/f8/35/8c80729f1ff76b3921d5c9487c7ac3de9b2a103b1cd05e905b3090513510/numpy-2.2.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2618db89be1b4e05f7a1a847a9c1c0abd63e63a1607d892dd54668dd92faf87", size = 14018462, upload-time = "2025-05-17T21:35:42.174Z" }, + { url = "https://files.pythonhosted.org/packages/8c/3d/1e1db36cfd41f895d266b103df00ca5b3cbe965184df824dec5c08c6b803/numpy-2.2.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd83c01228a688733f1ded5201c678f0c53ecc1006ffbc404db9f7a899ac6249", size = 16527618, upload-time = "2025-05-17T21:36:06.711Z" }, + { url = "https://files.pythonhosted.org/packages/61/c6/03ed30992602c85aa3cd95b9070a514f8b3c33e31124694438d88809ae36/numpy-2.2.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:37c0ca431f82cd5fa716eca9506aefcabc247fb27ba69c5062a6d3ade8cf8f49", size = 15505511, upload-time = "2025-05-17T21:36:29.965Z" }, + { url = "https://files.pythonhosted.org/packages/b7/25/5761d832a81df431e260719ec45de696414266613c9ee268394dd5ad8236/numpy-2.2.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fe27749d33bb772c80dcd84ae7e8df2adc920ae8297400dabec45f0dedb3f6de", size = 18313783, upload-time = "2025-05-17T21:36:56.883Z" }, + { url = "https://files.pythonhosted.org/packages/57/0a/72d5a3527c5ebffcd47bde9162c39fae1f90138c961e5296491ce778e682/numpy-2.2.6-cp312-cp312-win32.whl", hash = "sha256:4eeaae00d789f66c7a25ac5f34b71a7035bb474e679f410e5e1a94deb24cf2d4", size = 6246506, upload-time = "2025-05-17T21:37:07.368Z" }, + { url = "https://files.pythonhosted.org/packages/36/fa/8c9210162ca1b88529ab76b41ba02d433fd54fecaf6feb70ef9f124683f1/numpy-2.2.6-cp312-cp312-win_amd64.whl", hash = "sha256:c1f9540be57940698ed329904db803cf7a402f3fc200bfe599334c9bd84a40b2", size = 12614190, upload-time = "2025-05-17T21:37:26.213Z" }, + { url = "https://files.pythonhosted.org/packages/f9/5c/6657823f4f594f72b5471f1db1ab12e26e890bb2e41897522d134d2a3e81/numpy-2.2.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0811bb762109d9708cca4d0b13c4f67146e3c3b7cf8d34018c722adb2d957c84", size = 20867828, upload-time = "2025-05-17T21:37:56.699Z" }, + { url = "https://files.pythonhosted.org/packages/dc/9e/14520dc3dadf3c803473bd07e9b2bd1b69bc583cb2497b47000fed2fa92f/numpy-2.2.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:287cc3162b6f01463ccd86be154f284d0893d2b3ed7292439ea97eafa8170e0b", size = 14143006, upload-time = "2025-05-17T21:38:18.291Z" }, + { url = "https://files.pythonhosted.org/packages/4f/06/7e96c57d90bebdce9918412087fc22ca9851cceaf5567a45c1f404480e9e/numpy-2.2.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f1372f041402e37e5e633e586f62aa53de2eac8d98cbfb822806ce4bbefcb74d", size = 5076765, upload-time = "2025-05-17T21:38:27.319Z" }, + { url = "https://files.pythonhosted.org/packages/73/ed/63d920c23b4289fdac96ddbdd6132e9427790977d5457cd132f18e76eae0/numpy-2.2.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:55a4d33fa519660d69614a9fad433be87e5252f4b03850642f88993f7b2ca566", size = 6617736, upload-time = "2025-05-17T21:38:38.141Z" }, + { url = "https://files.pythonhosted.org/packages/85/c5/e19c8f99d83fd377ec8c7e0cf627a8049746da54afc24ef0a0cb73d5dfb5/numpy-2.2.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f92729c95468a2f4f15e9bb94c432a9229d0d50de67304399627a943201baa2f", size = 14010719, upload-time = "2025-05-17T21:38:58.433Z" }, + { url = "https://files.pythonhosted.org/packages/19/49/4df9123aafa7b539317bf6d342cb6d227e49f7a35b99c287a6109b13dd93/numpy-2.2.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f", size = 16526072, upload-time = "2025-05-17T21:39:22.638Z" }, + { url = "https://files.pythonhosted.org/packages/b2/6c/04b5f47f4f32f7c2b0e7260442a8cbcf8168b0e1a41ff1495da42f42a14f/numpy-2.2.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e3143e4451880bed956e706a3220b4e5cf6172ef05fcc397f6f36a550b1dd868", size = 15503213, upload-time = "2025-05-17T21:39:45.865Z" }, + { url = "https://files.pythonhosted.org/packages/17/0a/5cd92e352c1307640d5b6fec1b2ffb06cd0dabe7d7b8227f97933d378422/numpy-2.2.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4f13750ce79751586ae2eb824ba7e1e8dba64784086c98cdbbcc6a42112ce0d", size = 18316632, upload-time = "2025-05-17T21:40:13.331Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3b/5cba2b1d88760ef86596ad0f3d484b1cbff7c115ae2429678465057c5155/numpy-2.2.6-cp313-cp313-win32.whl", hash = "sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd", size = 6244532, upload-time = "2025-05-17T21:43:46.099Z" }, + { url = "https://files.pythonhosted.org/packages/cb/3b/d58c12eafcb298d4e6d0d40216866ab15f59e55d148a5658bb3132311fcf/numpy-2.2.6-cp313-cp313-win_amd64.whl", hash = "sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c", size = 12610885, upload-time = "2025-05-17T21:44:05.145Z" }, + { url = "https://files.pythonhosted.org/packages/6b/9e/4bf918b818e516322db999ac25d00c75788ddfd2d2ade4fa66f1f38097e1/numpy-2.2.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0bca768cd85ae743b2affdc762d617eddf3bcf8724435498a1e80132d04879e6", size = 20963467, upload-time = "2025-05-17T21:40:44Z" }, + { url = "https://files.pythonhosted.org/packages/61/66/d2de6b291507517ff2e438e13ff7b1e2cdbdb7cb40b3ed475377aece69f9/numpy-2.2.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fc0c5673685c508a142ca65209b4e79ed6740a4ed6b2267dbba90f34b0b3cfda", size = 14225144, upload-time = "2025-05-17T21:41:05.695Z" }, + { url = "https://files.pythonhosted.org/packages/e4/25/480387655407ead912e28ba3a820bc69af9adf13bcbe40b299d454ec011f/numpy-2.2.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:5bd4fc3ac8926b3819797a7c0e2631eb889b4118a9898c84f585a54d475b7e40", size = 5200217, upload-time = "2025-05-17T21:41:15.903Z" }, + { url = "https://files.pythonhosted.org/packages/aa/4a/6e313b5108f53dcbf3aca0c0f3e9c92f4c10ce57a0a721851f9785872895/numpy-2.2.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8", size = 6712014, upload-time = "2025-05-17T21:41:27.321Z" }, + { url = "https://files.pythonhosted.org/packages/b7/30/172c2d5c4be71fdf476e9de553443cf8e25feddbe185e0bd88b096915bcc/numpy-2.2.6-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1dda9c7e08dc141e0247a5b8f49cf05984955246a327d4c48bda16821947b2f", size = 14077935, upload-time = "2025-05-17T21:41:49.738Z" }, + { url = "https://files.pythonhosted.org/packages/12/fb/9e743f8d4e4d3c710902cf87af3512082ae3d43b945d5d16563f26ec251d/numpy-2.2.6-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f447e6acb680fd307f40d3da4852208af94afdfab89cf850986c3ca00562f4fa", size = 16600122, upload-time = "2025-05-17T21:42:14.046Z" }, + { url = "https://files.pythonhosted.org/packages/12/75/ee20da0e58d3a66f204f38916757e01e33a9737d0b22373b3eb5a27358f9/numpy-2.2.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:389d771b1623ec92636b0786bc4ae56abafad4a4c513d36a55dce14bd9ce8571", size = 15586143, upload-time = "2025-05-17T21:42:37.464Z" }, + { url = "https://files.pythonhosted.org/packages/76/95/bef5b37f29fc5e739947e9ce5179ad402875633308504a52d188302319c8/numpy-2.2.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8e9ace4a37db23421249ed236fdcdd457d671e25146786dfc96835cd951aa7c1", size = 18385260, upload-time = "2025-05-17T21:43:05.189Z" }, + { url = "https://files.pythonhosted.org/packages/09/04/f2f83279d287407cf36a7a8053a5abe7be3622a4363337338f2585e4afda/numpy-2.2.6-cp313-cp313t-win32.whl", hash = "sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff", size = 6377225, upload-time = "2025-05-17T21:43:16.254Z" }, + { url = "https://files.pythonhosted.org/packages/67/0e/35082d13c09c02c011cf21570543d202ad929d961c02a147493cb0c2bdf5/numpy-2.2.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06", size = 12771374, upload-time = "2025-05-17T21:43:35.479Z" }, +] + +[[package]] +name = "numpy-typing-compat" +version = "20250818.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d5/2c/6312cfc304b141bf9fa25a73dcd37d74a96cf411f0aa0f6df11f83e0b0ee/numpy_typing_compat-20250818.2.2.tar.gz", hash = "sha256:84f50c86908bf796857180856f1acb7da3c5bf22f461558de1cd225128c028ba", size = 4981, upload-time = "2025-08-18T23:46:42.17Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f3/36/4093816a4614df4d99ba71010736f1122acc2dbae316373575f17aaa2f8e/numpy_typing_compat-20250818.2.2-py3-none-any.whl", hash = "sha256:8b6c551952fd46e887ee905e75b6e4977d97defe1c63ae1b516343e9913e1534", size = 6292, upload-time = "2025-08-18T23:46:34.175Z" }, ] [[package]] @@ -1647,46 +1978,116 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "et-xmlfile" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3d/f9/88d94a75de065ea32619465d2f77b29a0469500e99012523b91cc4141cd1/openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050", size = 186464 } +sdist = { url = "https://files.pythonhosted.org/packages/3d/f9/88d94a75de065ea32619465d2f77b29a0469500e99012523b91cc4141cd1/openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050", size = 186464, upload-time = "2024-06-28T14:03:44.161Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c0/da/977ded879c29cbd04de313843e76868e6e13408a94ed6b987245dc7c8506/openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2", size = 250910 }, + { url = "https://files.pythonhosted.org/packages/c0/da/977ded879c29cbd04de313843e76868e6e13408a94ed6b987245dc7c8506/openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2", size = 250910, upload-time = "2024-06-28T14:03:41.161Z" }, ] [[package]] name = "optlang" -version = "1.5.2" +version = "1.8.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "six" }, { name = "swiglpk" }, { name = "sympy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/08/09/e87caa6d45be1bb5c787428822bc7694945d1bf2c9278939cbe5b2a11a2f/optlang-1.5.2.tar.gz", hash = "sha256:5514364aa06bf24381c6777188b2df79b13def2743312bdb80277392cdbb6477", size = 135085 } +sdist = { url = "https://files.pythonhosted.org/packages/f6/d3/555274e50193c1bd4795e16eddde833da06e563d8a57f03e1cdc38439f43/optlang-1.8.3.tar.gz", hash = "sha256:546a1c375b93734c636125fc1867aadb7e38ec276918960a9082eb12fb2cec5d", size = 137409, upload-time = "2025-01-08T12:45:31.973Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/52/18/8215ef740dd5b5d982de9c4cd352c99ce92c40c208245a2e8909bea7c0d6/optlang-1.8.3-py2.py3-none-any.whl", hash = "sha256:b81f4e873f0c1d0d907410add63aea427762d911245eb04a4a1126da5fedb595", size = 141752, upload-time = "2025-01-08T12:45:28.063Z" }, +] + +[[package]] +name = "optype" +version = "0.13.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/20/7f/daa32a35b2a6a564a79723da49c0ddc464c462e67a906fc2b66a0d64f28e/optype-0.13.4.tar.gz", hash = "sha256:131d8e0f1c12d8095d553e26b54598597133830983233a6a2208886e7a388432", size = 99547, upload-time = "2025-08-19T19:52:44.242Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/12/3e/9d0b72cf5a8ff660e5787a0797906e04942081f3ad4a95f860488affff2b/optlang-1.5.2-py2.py3-none-any.whl", hash = "sha256:14464cff638b58670c1a7f5896f19dd7b595a12c1d30a27c59074700833c1677", size = 147733 }, + { url = "https://files.pythonhosted.org/packages/37/bb/b51940f2d91071325d5ae2044562aa698470a105474d9317b9dbdaad63df/optype-0.13.4-py3-none-any.whl", hash = "sha256:500c89cfac82e2f9448a54ce0a5d5c415b6976b039c2494403cd6395bd531979", size = 87919, upload-time = "2025-08-19T19:52:41.314Z" }, +] + +[package.optional-dependencies] +numpy = [ + { name = "numpy" }, + { name = "numpy-typing-compat" }, +] + +[[package]] +name = "orjson" +version = "3.11.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/be/4d/8df5f83256a809c22c4d6792ce8d43bb503be0fb7a8e4da9025754b09658/orjson-3.11.3.tar.gz", hash = "sha256:1c0603b1d2ffcd43a411d64797a19556ef76958aef1c182f22dc30860152a98a", size = 5482394, upload-time = "2025-08-26T17:46:43.171Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cd/8b/360674cd817faef32e49276187922a946468579fcaf37afdfb6c07046e92/orjson-3.11.3-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:9d2ae0cc6aeb669633e0124531f342a17d8e97ea999e42f12a5ad4adaa304c5f", size = 238238, upload-time = "2025-08-26T17:44:54.214Z" }, + { url = "https://files.pythonhosted.org/packages/05/3d/5fa9ea4b34c1a13be7d9046ba98d06e6feb1d8853718992954ab59d16625/orjson-3.11.3-cp311-cp311-macosx_15_0_arm64.whl", hash = "sha256:ba21dbb2493e9c653eaffdc38819b004b7b1b246fb77bfc93dc016fe664eac91", size = 127713, upload-time = "2025-08-26T17:44:55.596Z" }, + { url = "https://files.pythonhosted.org/packages/e5/5f/e18367823925e00b1feec867ff5f040055892fc474bf5f7875649ecfa586/orjson-3.11.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00f1a271e56d511d1569937c0447d7dce5a99a33ea0dec76673706360a051904", size = 123241, upload-time = "2025-08-26T17:44:57.185Z" }, + { url = "https://files.pythonhosted.org/packages/0f/bd/3c66b91c4564759cf9f473251ac1650e446c7ba92a7c0f9f56ed54f9f0e6/orjson-3.11.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b67e71e47caa6680d1b6f075a396d04fa6ca8ca09aafb428731da9b3ea32a5a6", size = 127895, upload-time = "2025-08-26T17:44:58.349Z" }, + { url = "https://files.pythonhosted.org/packages/82/b5/dc8dcd609db4766e2967a85f63296c59d4722b39503e5b0bf7fd340d387f/orjson-3.11.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d7d012ebddffcce8c85734a6d9e5f08180cd3857c5f5a3ac70185b43775d043d", size = 130303, upload-time = "2025-08-26T17:44:59.491Z" }, + { url = "https://files.pythonhosted.org/packages/48/c2/d58ec5fd1270b2aa44c862171891adc2e1241bd7dab26c8f46eb97c6c6f1/orjson-3.11.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dd759f75d6b8d1b62012b7f5ef9461d03c804f94d539a5515b454ba3a6588038", size = 132366, upload-time = "2025-08-26T17:45:00.654Z" }, + { url = "https://files.pythonhosted.org/packages/73/87/0ef7e22eb8dd1ef940bfe3b9e441db519e692d62ed1aae365406a16d23d0/orjson-3.11.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6890ace0809627b0dff19cfad92d69d0fa3f089d3e359a2a532507bb6ba34efb", size = 135180, upload-time = "2025-08-26T17:45:02.424Z" }, + { url = "https://files.pythonhosted.org/packages/bb/6a/e5bf7b70883f374710ad74faf99bacfc4b5b5a7797c1d5e130350e0e28a3/orjson-3.11.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9d4a5e041ae435b815e568537755773d05dac031fee6a57b4ba70897a44d9d2", size = 132741, upload-time = "2025-08-26T17:45:03.663Z" }, + { url = "https://files.pythonhosted.org/packages/bd/0c/4577fd860b6386ffaa56440e792af01c7882b56d2766f55384b5b0e9d39b/orjson-3.11.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2d68bf97a771836687107abfca089743885fb664b90138d8761cce61d5625d55", size = 131104, upload-time = "2025-08-26T17:45:04.939Z" }, + { url = "https://files.pythonhosted.org/packages/66/4b/83e92b2d67e86d1c33f2ea9411742a714a26de63641b082bdbf3d8e481af/orjson-3.11.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:bfc27516ec46f4520b18ef645864cee168d2a027dbf32c5537cb1f3e3c22dac1", size = 403887, upload-time = "2025-08-26T17:45:06.228Z" }, + { url = "https://files.pythonhosted.org/packages/6d/e5/9eea6a14e9b5ceb4a271a1fd2e1dec5f2f686755c0fab6673dc6ff3433f4/orjson-3.11.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f66b001332a017d7945e177e282a40b6997056394e3ed7ddb41fb1813b83e824", size = 145855, upload-time = "2025-08-26T17:45:08.338Z" }, + { url = "https://files.pythonhosted.org/packages/45/78/8d4f5ad0c80ba9bf8ac4d0fc71f93a7d0dc0844989e645e2074af376c307/orjson-3.11.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:212e67806525d2561efbfe9e799633b17eb668b8964abed6b5319b2f1cfbae1f", size = 135361, upload-time = "2025-08-26T17:45:09.625Z" }, + { url = "https://files.pythonhosted.org/packages/0b/5f/16386970370178d7a9b438517ea3d704efcf163d286422bae3b37b88dbb5/orjson-3.11.3-cp311-cp311-win32.whl", hash = "sha256:6e8e0c3b85575a32f2ffa59de455f85ce002b8bdc0662d6b9c2ed6d80ab5d204", size = 136190, upload-time = "2025-08-26T17:45:10.962Z" }, + { url = "https://files.pythonhosted.org/packages/09/60/db16c6f7a41dd8ac9fb651f66701ff2aeb499ad9ebc15853a26c7c152448/orjson-3.11.3-cp311-cp311-win_amd64.whl", hash = "sha256:6be2f1b5d3dc99a5ce5ce162fc741c22ba9f3443d3dd586e6a1211b7bc87bc7b", size = 131389, upload-time = "2025-08-26T17:45:12.285Z" }, + { url = "https://files.pythonhosted.org/packages/3e/2a/bb811ad336667041dea9b8565c7c9faf2f59b47eb5ab680315eea612ef2e/orjson-3.11.3-cp311-cp311-win_arm64.whl", hash = "sha256:fafb1a99d740523d964b15c8db4eabbfc86ff29f84898262bf6e3e4c9e97e43e", size = 126120, upload-time = "2025-08-26T17:45:13.515Z" }, + { url = "https://files.pythonhosted.org/packages/3d/b0/a7edab2a00cdcb2688e1c943401cb3236323e7bfd2839815c6131a3742f4/orjson-3.11.3-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8c752089db84333e36d754c4baf19c0e1437012242048439c7e80eb0e6426e3b", size = 238259, upload-time = "2025-08-26T17:45:15.093Z" }, + { url = "https://files.pythonhosted.org/packages/e1/c6/ff4865a9cc398a07a83342713b5932e4dc3cb4bf4bc04e8f83dedfc0d736/orjson-3.11.3-cp312-cp312-macosx_15_0_arm64.whl", hash = "sha256:9b8761b6cf04a856eb544acdd82fc594b978f12ac3602d6374a7edb9d86fd2c2", size = 127633, upload-time = "2025-08-26T17:45:16.417Z" }, + { url = "https://files.pythonhosted.org/packages/6e/e6/e00bea2d9472f44fe8794f523e548ce0ad51eb9693cf538a753a27b8bda4/orjson-3.11.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b13974dc8ac6ba22feaa867fc19135a3e01a134b4f7c9c28162fed4d615008a", size = 123061, upload-time = "2025-08-26T17:45:17.673Z" }, + { url = "https://files.pythonhosted.org/packages/54/31/9fbb78b8e1eb3ac605467cb846e1c08d0588506028b37f4ee21f978a51d4/orjson-3.11.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f83abab5bacb76d9c821fd5c07728ff224ed0e52d7a71b7b3de822f3df04e15c", size = 127956, upload-time = "2025-08-26T17:45:19.172Z" }, + { url = "https://files.pythonhosted.org/packages/36/88/b0604c22af1eed9f98d709a96302006915cfd724a7ebd27d6dd11c22d80b/orjson-3.11.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e6fbaf48a744b94091a56c62897b27c31ee2da93d826aa5b207131a1e13d4064", size = 130790, upload-time = "2025-08-26T17:45:20.586Z" }, + { url = "https://files.pythonhosted.org/packages/0e/9d/1c1238ae9fffbfed51ba1e507731b3faaf6b846126a47e9649222b0fd06f/orjson-3.11.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc779b4f4bba2847d0d2940081a7b6f7b5877e05408ffbb74fa1faf4a136c424", size = 132385, upload-time = "2025-08-26T17:45:22.036Z" }, + { url = "https://files.pythonhosted.org/packages/a3/b5/c06f1b090a1c875f337e21dd71943bc9d84087f7cdf8c6e9086902c34e42/orjson-3.11.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd4b909ce4c50faa2192da6bb684d9848d4510b736b0611b6ab4020ea6fd2d23", size = 135305, upload-time = "2025-08-26T17:45:23.4Z" }, + { url = "https://files.pythonhosted.org/packages/a0/26/5f028c7d81ad2ebbf84414ba6d6c9cac03f22f5cd0d01eb40fb2d6a06b07/orjson-3.11.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:524b765ad888dc5518bbce12c77c2e83dee1ed6b0992c1790cc5fb49bb4b6667", size = 132875, upload-time = "2025-08-26T17:45:25.182Z" }, + { url = "https://files.pythonhosted.org/packages/fe/d4/b8df70d9cfb56e385bf39b4e915298f9ae6c61454c8154a0f5fd7efcd42e/orjson-3.11.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:84fd82870b97ae3cdcea9d8746e592b6d40e1e4d4527835fc520c588d2ded04f", size = 130940, upload-time = "2025-08-26T17:45:27.209Z" }, + { url = "https://files.pythonhosted.org/packages/da/5e/afe6a052ebc1a4741c792dd96e9f65bf3939d2094e8b356503b68d48f9f5/orjson-3.11.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:fbecb9709111be913ae6879b07bafd4b0785b44c1eb5cac8ac76da048b3885a1", size = 403852, upload-time = "2025-08-26T17:45:28.478Z" }, + { url = "https://files.pythonhosted.org/packages/f8/90/7bbabafeb2ce65915e9247f14a56b29c9334003536009ef5b122783fe67e/orjson-3.11.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:9dba358d55aee552bd868de348f4736ca5a4086d9a62e2bfbbeeb5629fe8b0cc", size = 146293, upload-time = "2025-08-26T17:45:29.86Z" }, + { url = "https://files.pythonhosted.org/packages/27/b3/2d703946447da8b093350570644a663df69448c9d9330e5f1d9cce997f20/orjson-3.11.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:eabcf2e84f1d7105f84580e03012270c7e97ecb1fb1618bda395061b2a84a049", size = 135470, upload-time = "2025-08-26T17:45:31.243Z" }, + { url = "https://files.pythonhosted.org/packages/38/70/b14dcfae7aff0e379b0119c8a812f8396678919c431efccc8e8a0263e4d9/orjson-3.11.3-cp312-cp312-win32.whl", hash = "sha256:3782d2c60b8116772aea8d9b7905221437fdf53e7277282e8d8b07c220f96cca", size = 136248, upload-time = "2025-08-26T17:45:32.567Z" }, + { url = "https://files.pythonhosted.org/packages/35/b8/9e3127d65de7fff243f7f3e53f59a531bf6bb295ebe5db024c2503cc0726/orjson-3.11.3-cp312-cp312-win_amd64.whl", hash = "sha256:79b44319268af2eaa3e315b92298de9a0067ade6e6003ddaef72f8e0bedb94f1", size = 131437, upload-time = "2025-08-26T17:45:34.949Z" }, + { url = "https://files.pythonhosted.org/packages/51/92/a946e737d4d8a7fd84a606aba96220043dcc7d6988b9e7551f7f6d5ba5ad/orjson-3.11.3-cp312-cp312-win_arm64.whl", hash = "sha256:0e92a4e83341ef79d835ca21b8bd13e27c859e4e9e4d7b63defc6e58462a3710", size = 125978, upload-time = "2025-08-26T17:45:36.422Z" }, + { url = "https://files.pythonhosted.org/packages/fc/79/8932b27293ad35919571f77cb3693b5906cf14f206ef17546052a241fdf6/orjson-3.11.3-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:af40c6612fd2a4b00de648aa26d18186cd1322330bd3a3cc52f87c699e995810", size = 238127, upload-time = "2025-08-26T17:45:38.146Z" }, + { url = "https://files.pythonhosted.org/packages/1c/82/cb93cd8cf132cd7643b30b6c5a56a26c4e780c7a145db6f83de977b540ce/orjson-3.11.3-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:9f1587f26c235894c09e8b5b7636a38091a9e6e7fe4531937534749c04face43", size = 127494, upload-time = "2025-08-26T17:45:39.57Z" }, + { url = "https://files.pythonhosted.org/packages/a4/b8/2d9eb181a9b6bb71463a78882bcac1027fd29cf62c38a40cc02fc11d3495/orjson-3.11.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:61dcdad16da5bb486d7227a37a2e789c429397793a6955227cedbd7252eb5a27", size = 123017, upload-time = "2025-08-26T17:45:40.876Z" }, + { url = "https://files.pythonhosted.org/packages/b4/14/a0e971e72d03b509190232356d54c0f34507a05050bd026b8db2bf2c192c/orjson-3.11.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:11c6d71478e2cbea0a709e8a06365fa63da81da6498a53e4c4f065881d21ae8f", size = 127898, upload-time = "2025-08-26T17:45:42.188Z" }, + { url = "https://files.pythonhosted.org/packages/8e/af/dc74536722b03d65e17042cc30ae586161093e5b1f29bccda24765a6ae47/orjson-3.11.3-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff94112e0098470b665cb0ed06efb187154b63649403b8d5e9aedeb482b4548c", size = 130742, upload-time = "2025-08-26T17:45:43.511Z" }, + { url = "https://files.pythonhosted.org/packages/62/e6/7a3b63b6677bce089fe939353cda24a7679825c43a24e49f757805fc0d8a/orjson-3.11.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae8b756575aaa2a855a75192f356bbda11a89169830e1439cfb1a3e1a6dde7be", size = 132377, upload-time = "2025-08-26T17:45:45.525Z" }, + { url = "https://files.pythonhosted.org/packages/fc/cd/ce2ab93e2e7eaf518f0fd15e3068b8c43216c8a44ed82ac2b79ce5cef72d/orjson-3.11.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c9416cc19a349c167ef76135b2fe40d03cea93680428efee8771f3e9fb66079d", size = 135313, upload-time = "2025-08-26T17:45:46.821Z" }, + { url = "https://files.pythonhosted.org/packages/d0/b4/f98355eff0bd1a38454209bbc73372ce351ba29933cb3e2eba16c04b9448/orjson-3.11.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b822caf5b9752bc6f246eb08124c3d12bf2175b66ab74bac2ef3bbf9221ce1b2", size = 132908, upload-time = "2025-08-26T17:45:48.126Z" }, + { url = "https://files.pythonhosted.org/packages/eb/92/8f5182d7bc2a1bed46ed960b61a39af8389f0ad476120cd99e67182bfb6d/orjson-3.11.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:414f71e3bdd5573893bf5ecdf35c32b213ed20aa15536fe2f588f946c318824f", size = 130905, upload-time = "2025-08-26T17:45:49.414Z" }, + { url = "https://files.pythonhosted.org/packages/1a/60/c41ca753ce9ffe3d0f67b9b4c093bdd6e5fdb1bc53064f992f66bb99954d/orjson-3.11.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:828e3149ad8815dc14468f36ab2a4b819237c155ee1370341b91ea4c8672d2ee", size = 403812, upload-time = "2025-08-26T17:45:51.085Z" }, + { url = "https://files.pythonhosted.org/packages/dd/13/e4a4f16d71ce1868860db59092e78782c67082a8f1dc06a3788aef2b41bc/orjson-3.11.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ac9e05f25627ffc714c21f8dfe3a579445a5c392a9c8ae7ba1d0e9fb5333f56e", size = 146277, upload-time = "2025-08-26T17:45:52.851Z" }, + { url = "https://files.pythonhosted.org/packages/8d/8b/bafb7f0afef9344754a3a0597a12442f1b85a048b82108ef2c956f53babd/orjson-3.11.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e44fbe4000bd321d9f3b648ae46e0196d21577cf66ae684a96ff90b1f7c93633", size = 135418, upload-time = "2025-08-26T17:45:54.806Z" }, + { url = "https://files.pythonhosted.org/packages/60/d4/bae8e4f26afb2c23bea69d2f6d566132584d1c3a5fe89ee8c17b718cab67/orjson-3.11.3-cp313-cp313-win32.whl", hash = "sha256:2039b7847ba3eec1f5886e75e6763a16e18c68a63efc4b029ddf994821e2e66b", size = 136216, upload-time = "2025-08-26T17:45:57.182Z" }, + { url = "https://files.pythonhosted.org/packages/88/76/224985d9f127e121c8cad882cea55f0ebe39f97925de040b75ccd4b33999/orjson-3.11.3-cp313-cp313-win_amd64.whl", hash = "sha256:29be5ac4164aa8bdcba5fa0700a3c9c316b411d8ed9d39ef8a882541bd452fae", size = 131362, upload-time = "2025-08-26T17:45:58.56Z" }, + { url = "https://files.pythonhosted.org/packages/e2/cf/0dce7a0be94bd36d1346be5067ed65ded6adb795fdbe3abd234c8d576d01/orjson-3.11.3-cp313-cp313-win_arm64.whl", hash = "sha256:18bd1435cb1f2857ceb59cfb7de6f92593ef7b831ccd1b9bfb28ca530e539dce", size = 125989, upload-time = "2025-08-26T17:45:59.95Z" }, ] [[package]] name = "overrides" version = "7.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/36/86/b585f53236dec60aba864e050778b25045f857e17f6e5ea0ae95fe80edd2/overrides-7.7.0.tar.gz", hash = "sha256:55158fa3d93b98cc75299b1e67078ad9003ca27945c76162c1c0766d6f91820a", size = 22812 } +sdist = { url = "https://files.pythonhosted.org/packages/36/86/b585f53236dec60aba864e050778b25045f857e17f6e5ea0ae95fe80edd2/overrides-7.7.0.tar.gz", hash = "sha256:55158fa3d93b98cc75299b1e67078ad9003ca27945c76162c1c0766d6f91820a", size = 22812, upload-time = "2024-01-27T21:01:33.423Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/ab/fc8290c6a4c722e5514d80f62b2dc4c4df1a68a41d1364e625c35990fcf3/overrides-7.7.0-py3-none-any.whl", hash = "sha256:c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49", size = 17832 }, + { url = "https://files.pythonhosted.org/packages/2c/ab/fc8290c6a4c722e5514d80f62b2dc4c4df1a68a41d1364e625c35990fcf3/overrides-7.7.0-py3-none-any.whl", hash = "sha256:c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49", size = 17832, upload-time = "2024-01-27T21:01:31.393Z" }, ] [[package]] name = "packaging" -version = "24.1" +version = "25.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/51/65/50db4dda066951078f0a96cf12f4b9ada6e4b811516bf0262c0f4f7064d4/packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", size = 148788 } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/08/aa/cc0199a5f0ad350994d660967a8efb233fe0416e4639146c089643407ce6/packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124", size = 53985 }, + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, ] [[package]] name = "pandas" -version = "2.2.3" +version = "2.3.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, @@ -1694,52 +2095,71 @@ dependencies = [ { name = "pytz" }, { name = "tzdata" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9c/d6/9f8431bacc2e19dca897724cd097b1bb224a6ad5433784a44b587c7c13af/pandas-2.2.3.tar.gz", hash = "sha256:4f18ba62b61d7e192368b84517265a99b4d7ee8912f8708660fb4a366cc82667", size = 4399213 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/aa/70/c853aec59839bceed032d52010ff5f1b8d87dc3114b762e4ba2727661a3b/pandas-2.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1948ddde24197a0f7add2bdc4ca83bf2b1ef84a1bc8ccffd95eda17fd836ecb5", size = 12580827 }, - { url = "https://files.pythonhosted.org/packages/99/f2/c4527768739ffa4469b2b4fff05aa3768a478aed89a2f271a79a40eee984/pandas-2.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:381175499d3802cde0eabbaf6324cce0c4f5d52ca6f8c377c29ad442f50f6348", size = 11303897 }, - { url = "https://files.pythonhosted.org/packages/ed/12/86c1747ea27989d7a4064f806ce2bae2c6d575b950be087837bdfcabacc9/pandas-2.2.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d9c45366def9a3dd85a6454c0e7908f2b3b8e9c138f5dc38fed7ce720d8453ed", size = 66480908 }, - { url = "https://files.pythonhosted.org/packages/44/50/7db2cd5e6373ae796f0ddad3675268c8d59fb6076e66f0c339d61cea886b/pandas-2.2.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86976a1c5b25ae3f8ccae3a5306e443569ee3c3faf444dfd0f41cda24667ad57", size = 13064210 }, - { url = "https://files.pythonhosted.org/packages/61/61/a89015a6d5536cb0d6c3ba02cebed51a95538cf83472975275e28ebf7d0c/pandas-2.2.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b8661b0238a69d7aafe156b7fa86c44b881387509653fdf857bebc5e4008ad42", size = 16754292 }, - { url = "https://files.pythonhosted.org/packages/ce/0d/4cc7b69ce37fac07645a94e1d4b0880b15999494372c1523508511b09e40/pandas-2.2.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:37e0aced3e8f539eccf2e099f65cdb9c8aa85109b0be6e93e2baff94264bdc6f", size = 14416379 }, - { url = "https://files.pythonhosted.org/packages/31/9e/6ebb433de864a6cd45716af52a4d7a8c3c9aaf3a98368e61db9e69e69a9c/pandas-2.2.3-cp310-cp310-win_amd64.whl", hash = "sha256:56534ce0746a58afaf7942ba4863e0ef81c9c50d3f0ae93e9497d6a41a057645", size = 11598471 }, - { url = "https://files.pythonhosted.org/packages/a8/44/d9502bf0ed197ba9bf1103c9867d5904ddcaf869e52329787fc54ed70cc8/pandas-2.2.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:66108071e1b935240e74525006034333f98bcdb87ea116de573a6a0dccb6c039", size = 12602222 }, - { url = "https://files.pythonhosted.org/packages/52/11/9eac327a38834f162b8250aab32a6781339c69afe7574368fffe46387edf/pandas-2.2.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7c2875855b0ff77b2a64a0365e24455d9990730d6431b9e0ee18ad8acee13dbd", size = 11321274 }, - { url = "https://files.pythonhosted.org/packages/45/fb/c4beeb084718598ba19aa9f5abbc8aed8b42f90930da861fcb1acdb54c3a/pandas-2.2.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd8d0c3be0515c12fed0bdbae072551c8b54b7192c7b1fda0ba56059a0179698", size = 15579836 }, - { url = "https://files.pythonhosted.org/packages/cd/5f/4dba1d39bb9c38d574a9a22548c540177f78ea47b32f99c0ff2ec499fac5/pandas-2.2.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c124333816c3a9b03fbeef3a9f230ba9a737e9e5bb4060aa2107a86cc0a497fc", size = 13058505 }, - { url = "https://files.pythonhosted.org/packages/b9/57/708135b90391995361636634df1f1130d03ba456e95bcf576fada459115a/pandas-2.2.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:63cc132e40a2e084cf01adf0775b15ac515ba905d7dcca47e9a251819c575ef3", size = 16744420 }, - { url = "https://files.pythonhosted.org/packages/86/4a/03ed6b7ee323cf30404265c284cee9c65c56a212e0a08d9ee06984ba2240/pandas-2.2.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:29401dbfa9ad77319367d36940cd8a0b3a11aba16063e39632d98b0e931ddf32", size = 14440457 }, - { url = "https://files.pythonhosted.org/packages/ed/8c/87ddf1fcb55d11f9f847e3c69bb1c6f8e46e2f40ab1a2d2abadb2401b007/pandas-2.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:3fc6873a41186404dad67245896a6e440baacc92f5b716ccd1bc9ed2995ab2c5", size = 11617166 }, - { url = "https://files.pythonhosted.org/packages/17/a3/fb2734118db0af37ea7433f57f722c0a56687e14b14690edff0cdb4b7e58/pandas-2.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b1d432e8d08679a40e2a6d8b2f9770a5c21793a6f9f47fdd52c5ce1948a5a8a9", size = 12529893 }, - { url = "https://files.pythonhosted.org/packages/e1/0c/ad295fd74bfac85358fd579e271cded3ac969de81f62dd0142c426b9da91/pandas-2.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a5a1595fe639f5988ba6a8e5bc9649af3baf26df3998a0abe56c02609392e0a4", size = 11363475 }, - { url = "https://files.pythonhosted.org/packages/c6/2a/4bba3f03f7d07207481fed47f5b35f556c7441acddc368ec43d6643c5777/pandas-2.2.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5de54125a92bb4d1c051c0659e6fcb75256bf799a732a87184e5ea503965bce3", size = 15188645 }, - { url = "https://files.pythonhosted.org/packages/38/f8/d8fddee9ed0d0c0f4a2132c1dfcf0e3e53265055da8df952a53e7eaf178c/pandas-2.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fffb8ae78d8af97f849404f21411c95062db1496aeb3e56f146f0355c9989319", size = 12739445 }, - { url = "https://files.pythonhosted.org/packages/20/e8/45a05d9c39d2cea61ab175dbe6a2de1d05b679e8de2011da4ee190d7e748/pandas-2.2.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dfcb5ee8d4d50c06a51c2fffa6cff6272098ad6540aed1a76d15fb9318194d8", size = 16359235 }, - { url = "https://files.pythonhosted.org/packages/1d/99/617d07a6a5e429ff90c90da64d428516605a1ec7d7bea494235e1c3882de/pandas-2.2.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:062309c1b9ea12a50e8ce661145c6aab431b1e99530d3cd60640e255778bd43a", size = 14056756 }, - { url = "https://files.pythonhosted.org/packages/29/d4/1244ab8edf173a10fd601f7e13b9566c1b525c4f365d6bee918e68381889/pandas-2.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:59ef3764d0fe818125a5097d2ae867ca3fa64df032331b7e0917cf5d7bf66b13", size = 11504248 }, +sdist = { url = "https://files.pythonhosted.org/packages/79/8e/0e90233ac205ad182bd6b422532695d2b9414944a280488105d598c70023/pandas-2.3.2.tar.gz", hash = "sha256:ab7b58f8f82706890924ccdfb5f48002b83d2b5a3845976a9fb705d36c34dcdb", size = 4488684, upload-time = "2025-08-21T10:28:29.257Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7a/59/f3e010879f118c2d400902d2d871c2226cef29b08c09fb8dc41111730400/pandas-2.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1333e9c299adcbb68ee89a9bb568fc3f20f9cbb419f1dd5225071e6cddb2a743", size = 11563308, upload-time = "2025-08-21T10:26:56.656Z" }, + { url = "https://files.pythonhosted.org/packages/38/18/48f10f1cc5c397af59571d638d211f494dba481f449c19adbd282aa8f4ca/pandas-2.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:76972bcbd7de8e91ad5f0ca884a9f2c477a2125354af624e022c49e5bd0dfff4", size = 10820319, upload-time = "2025-08-21T10:26:59.162Z" }, + { url = "https://files.pythonhosted.org/packages/95/3b/1e9b69632898b048e223834cd9702052bcf06b15e1ae716eda3196fb972e/pandas-2.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b98bdd7c456a05eef7cd21fd6b29e3ca243591fe531c62be94a2cc987efb5ac2", size = 11790097, upload-time = "2025-08-21T10:27:02.204Z" }, + { url = "https://files.pythonhosted.org/packages/8b/ef/0e2ffb30b1f7fbc9a588bd01e3c14a0d96854d09a887e15e30cc19961227/pandas-2.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d81573b3f7db40d020983f78721e9bfc425f411e616ef019a10ebf597aedb2e", size = 12397958, upload-time = "2025-08-21T10:27:05.409Z" }, + { url = "https://files.pythonhosted.org/packages/23/82/e6b85f0d92e9afb0e7f705a51d1399b79c7380c19687bfbf3d2837743249/pandas-2.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e190b738675a73b581736cc8ec71ae113d6c3768d0bd18bffa5b9a0927b0b6ea", size = 13225600, upload-time = "2025-08-21T10:27:07.791Z" }, + { url = "https://files.pythonhosted.org/packages/e8/f1/f682015893d9ed51611948bd83683670842286a8edd4f68c2c1c3b231eef/pandas-2.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c253828cb08f47488d60f43c5fc95114c771bbfff085da54bfc79cb4f9e3a372", size = 13879433, upload-time = "2025-08-21T10:27:10.347Z" }, + { url = "https://files.pythonhosted.org/packages/a7/e7/ae86261695b6c8a36d6a4c8d5f9b9ede8248510d689a2f379a18354b37d7/pandas-2.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:9467697b8083f9667b212633ad6aa4ab32436dcbaf4cd57325debb0ddef2012f", size = 11336557, upload-time = "2025-08-21T10:27:12.983Z" }, + { url = "https://files.pythonhosted.org/packages/ec/db/614c20fb7a85a14828edd23f1c02db58a30abf3ce76f38806155d160313c/pandas-2.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3fbb977f802156e7a3f829e9d1d5398f6192375a3e2d1a9ee0803e35fe70a2b9", size = 11587652, upload-time = "2025-08-21T10:27:15.888Z" }, + { url = "https://files.pythonhosted.org/packages/99/b0/756e52f6582cade5e746f19bad0517ff27ba9c73404607c0306585c201b3/pandas-2.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1b9b52693123dd234b7c985c68b709b0b009f4521000d0525f2b95c22f15944b", size = 10717686, upload-time = "2025-08-21T10:27:18.486Z" }, + { url = "https://files.pythonhosted.org/packages/37/4c/dd5ccc1e357abfeee8353123282de17997f90ff67855f86154e5a13b81e5/pandas-2.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bd281310d4f412733f319a5bc552f86d62cddc5f51d2e392c8787335c994175", size = 11278722, upload-time = "2025-08-21T10:27:21.149Z" }, + { url = "https://files.pythonhosted.org/packages/d3/a4/f7edcfa47e0a88cda0be8b068a5bae710bf264f867edfdf7b71584ace362/pandas-2.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96d31a6b4354e3b9b8a2c848af75d31da390657e3ac6f30c05c82068b9ed79b9", size = 11987803, upload-time = "2025-08-21T10:27:23.767Z" }, + { url = "https://files.pythonhosted.org/packages/f6/61/1bce4129f93ab66f1c68b7ed1c12bac6a70b1b56c5dab359c6bbcd480b52/pandas-2.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:df4df0b9d02bb873a106971bb85d448378ef14b86ba96f035f50bbd3688456b4", size = 12766345, upload-time = "2025-08-21T10:27:26.6Z" }, + { url = "https://files.pythonhosted.org/packages/8e/46/80d53de70fee835531da3a1dae827a1e76e77a43ad22a8cd0f8142b61587/pandas-2.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:213a5adf93d020b74327cb2c1b842884dbdd37f895f42dcc2f09d451d949f811", size = 13439314, upload-time = "2025-08-21T10:27:29.213Z" }, + { url = "https://files.pythonhosted.org/packages/28/30/8114832daff7489f179971dbc1d854109b7f4365a546e3ea75b6516cea95/pandas-2.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:8c13b81a9347eb8c7548f53fd9a4f08d4dfe996836543f805c987bafa03317ae", size = 10983326, upload-time = "2025-08-21T10:27:31.901Z" }, + { url = "https://files.pythonhosted.org/packages/27/64/a2f7bf678af502e16b472527735d168b22b7824e45a4d7e96a4fbb634b59/pandas-2.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0c6ecbac99a354a051ef21c5307601093cb9e0f4b1855984a084bfec9302699e", size = 11531061, upload-time = "2025-08-21T10:27:34.647Z" }, + { url = "https://files.pythonhosted.org/packages/54/4c/c3d21b2b7769ef2f4c2b9299fcadd601efa6729f1357a8dbce8dd949ed70/pandas-2.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c6f048aa0fd080d6a06cc7e7537c09b53be6642d330ac6f54a600c3ace857ee9", size = 10668666, upload-time = "2025-08-21T10:27:37.203Z" }, + { url = "https://files.pythonhosted.org/packages/50/e2/f775ba76ecfb3424d7f5862620841cf0edb592e9abd2d2a5387d305fe7a8/pandas-2.3.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0064187b80a5be6f2f9c9d6bdde29372468751dfa89f4211a3c5871854cfbf7a", size = 11332835, upload-time = "2025-08-21T10:27:40.188Z" }, + { url = "https://files.pythonhosted.org/packages/8f/52/0634adaace9be2d8cac9ef78f05c47f3a675882e068438b9d7ec7ef0c13f/pandas-2.3.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ac8c320bded4718b298281339c1a50fb00a6ba78cb2a63521c39bec95b0209b", size = 12057211, upload-time = "2025-08-21T10:27:43.117Z" }, + { url = "https://files.pythonhosted.org/packages/0b/9d/2df913f14b2deb9c748975fdb2491da1a78773debb25abbc7cbc67c6b549/pandas-2.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:114c2fe4f4328cf98ce5716d1532f3ab79c5919f95a9cfee81d9140064a2e4d6", size = 12749277, upload-time = "2025-08-21T10:27:45.474Z" }, + { url = "https://files.pythonhosted.org/packages/87/af/da1a2417026bd14d98c236dba88e39837182459d29dcfcea510b2ac9e8a1/pandas-2.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:48fa91c4dfb3b2b9bfdb5c24cd3567575f4e13f9636810462ffed8925352be5a", size = 13415256, upload-time = "2025-08-21T10:27:49.885Z" }, + { url = "https://files.pythonhosted.org/packages/22/3c/f2af1ce8840ef648584a6156489636b5692c162771918aa95707c165ad2b/pandas-2.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:12d039facec710f7ba305786837d0225a3444af7bbd9c15c32ca2d40d157ed8b", size = 10982579, upload-time = "2025-08-21T10:28:08.435Z" }, + { url = "https://files.pythonhosted.org/packages/f3/98/8df69c4097a6719e357dc249bf437b8efbde808038268e584421696cbddf/pandas-2.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:c624b615ce97864eb588779ed4046186f967374185c047070545253a52ab2d57", size = 12028163, upload-time = "2025-08-21T10:27:52.232Z" }, + { url = "https://files.pythonhosted.org/packages/0e/23/f95cbcbea319f349e10ff90db488b905c6883f03cbabd34f6b03cbc3c044/pandas-2.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0cee69d583b9b128823d9514171cabb6861e09409af805b54459bd0c821a35c2", size = 11391860, upload-time = "2025-08-21T10:27:54.673Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1b/6a984e98c4abee22058aa75bfb8eb90dce58cf8d7296f8bc56c14bc330b0/pandas-2.3.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2319656ed81124982900b4c37f0e0c58c015af9a7bbc62342ba5ad07ace82ba9", size = 11309830, upload-time = "2025-08-21T10:27:56.957Z" }, + { url = "https://files.pythonhosted.org/packages/15/d5/f0486090eb18dd8710bf60afeaf638ba6817047c0c8ae5c6a25598665609/pandas-2.3.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b37205ad6f00d52f16b6d09f406434ba928c1a1966e2771006a9033c736d30d2", size = 11883216, upload-time = "2025-08-21T10:27:59.302Z" }, + { url = "https://files.pythonhosted.org/packages/10/86/692050c119696da19e20245bbd650d8dfca6ceb577da027c3a73c62a047e/pandas-2.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:837248b4fc3a9b83b9c6214699a13f069dc13510a6a6d7f9ba33145d2841a012", size = 12699743, upload-time = "2025-08-21T10:28:02.447Z" }, + { url = "https://files.pythonhosted.org/packages/cd/d7/612123674d7b17cf345aad0a10289b2a384bff404e0463a83c4a3a59d205/pandas-2.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d2c3554bd31b731cd6490d94a28f3abb8dd770634a9e06eb6d2911b9827db370", size = 13186141, upload-time = "2025-08-21T10:28:05.377Z" }, +] + +[[package]] +name = "pandas-stubs" +version = "2.3.2.250827" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "types-pytz" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/03/7b/8d2076a76ddf35806319798037056e4bbdcacdc832fb7c95b517f4c03fb2/pandas_stubs-2.3.2.250827.tar.gz", hash = "sha256:bcc2d49a2766325e4a1a492c3eeda879e9521bb5e26e69e2bbf13e80e7ef569a", size = 100032, upload-time = "2025-08-27T23:18:12.802Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a1/b8/dc820157be5aa9527f1f7ffe81737ee4d1cf0924081e1bfbd680530dde41/pandas_stubs-2.3.2.250827-py3-none-any.whl", hash = "sha256:3d613013b4189147a9a6bb18d8bec1e5b137de091496e9b9ff9f137ec3e223a9", size = 157775, upload-time = "2025-08-27T23:18:11.083Z" }, ] [[package]] name = "pandocfilters" version = "1.5.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/70/6f/3dd4940bbe001c06a65f88e36bad298bc7a0de5036115639926b0c5c0458/pandocfilters-1.5.1.tar.gz", hash = "sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e", size = 8454 } +sdist = { url = "https://files.pythonhosted.org/packages/70/6f/3dd4940bbe001c06a65f88e36bad298bc7a0de5036115639926b0c5c0458/pandocfilters-1.5.1.tar.gz", hash = "sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e", size = 8454, upload-time = "2024-01-18T20:08:13.726Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl", hash = "sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc", size = 8663 }, + { url = "https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl", hash = "sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc", size = 8663, upload-time = "2024-01-18T20:08:11.28Z" }, ] [[package]] name = "parso" -version = "0.8.4" +version = "0.8.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/66/94/68e2e17afaa9169cf6412ab0f28623903be73d1b32e208d9e8e541bb086d/parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d", size = 400609 } +sdist = { url = "https://files.pythonhosted.org/packages/d4/de/53e0bcf53d13e005bd8c92e7855142494f41171b34c2536b86187474184d/parso-0.8.5.tar.gz", hash = "sha256:034d7354a9a018bdce352f48b2a8a450f05e9d6ee85db84764e9b6bd96dafe5a", size = 401205, upload-time = "2025-08-23T15:15:28.028Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c6/ac/dac4a63f978e4dcb3c6d3a78c4d8e0192a113d288502a1216950c41b1027/parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18", size = 103650 }, + { url = "https://files.pythonhosted.org/packages/16/32/f8e3c85d1d5250232a5d3477a2a28cc291968ff175caeadaf3cc19ce0e4a/parso-0.8.5-py2.py3-none-any.whl", hash = "sha256:646204b5ee239c396d040b90f9e272e9a8017c630092bf59980beb62fd033887", size = 106668, upload-time = "2025-08-23T15:15:25.663Z" }, ] [[package]] name = "pathos" -version = "0.3.3" +version = "0.3.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "dill" }, @@ -1747,22 +2167,21 @@ dependencies = [ { name = "pox" }, { name = "ppft" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5b/a4/6274bddc49a00873d3269b7612c1553763bae6466c0c82913e16810abd51/pathos-0.3.3.tar.gz", hash = "sha256:dcb2a5f321aa34ca541c1c1861011ea49df357bb908379c21dd5741f666e0a58", size = 166953 } +sdist = { url = "https://files.pythonhosted.org/packages/be/90/fdbe3bbfe79933db439e1844083cb6e9d5a9d3b686738549b3d22d06eae7/pathos-0.3.4.tar.gz", hash = "sha256:bad4912d0ef865654a7cc478da65f2e1d5b69f3d92c4a7d9c9845657783c0754", size = 167076, upload-time = "2025-04-17T03:37:08.234Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/77/f6/a459cf58ff6b2d1c0a1961ee7084f4bb549d50e288f064e7e7be5ae3a7ab/pathos-0.3.3-py3-none-any.whl", hash = "sha256:e04616c6448608ad1f809360be22e3f2078d949a36a81e6991da6c2dd1f82513", size = 82142 }, + { url = "https://files.pythonhosted.org/packages/11/0a/daece46e65c821d153746566a1604ac90338f0279b1fb858a3617eb60472/pathos-0.3.4-py3-none-any.whl", hash = "sha256:fe44883448c05c80d518b61df491b496f6190bb6860253f3254d8c9afb53c340", size = 82261, upload-time = "2025-04-17T03:37:06.936Z" }, ] [[package]] name = "patsy" -version = "0.5.6" +version = "1.0.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, - { name = "six" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c6/18/12e76e52d589c4a812a2f1fb2406b486c226b7ac263ac8ef4b5f4bb04058/patsy-0.5.6.tar.gz", hash = "sha256:95c6d47a7222535f84bff7f63d7303f2e297747a598db89cf5c67f0c0c7d2cdb", size = 398011 } +sdist = { url = "https://files.pythonhosted.org/packages/d1/81/74f6a65b848ffd16c18f920620ce999fe45fe27f01ab3911260ce4ed85e4/patsy-1.0.1.tar.gz", hash = "sha256:e786a9391eec818c054e359b737bbce692f051aee4c661f4141cc88fb459c0c4", size = 396010, upload-time = "2024-11-12T14:10:54.642Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/43/f3/1d311a09c34f14f5973bb0bb0dc3a6e007e1eda90b5492d082689936ca51/patsy-0.5.6-py2.py3-none-any.whl", hash = "sha256:19056886fd8fa71863fa32f0eb090267f21fb74be00f19f5c70b2e9d76c883c6", size = 233945 }, + { url = "https://files.pythonhosted.org/packages/87/2b/b50d3d08ea0fc419c183a84210571eba005328efa62b6b98bc28e9ead32a/patsy-1.0.1-py2.py3-none-any.whl", hash = "sha256:751fb38f9e97e62312e921a1954b81e1bb2bcda4f5eeabaf94db251ee791509c", size = 232923, upload-time = "2024-11-12T14:10:52.85Z" }, ] [[package]] @@ -1772,240 +2191,290 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "ptyprocess" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450 } +sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772 }, + { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772, upload-time = "2023-11-25T06:56:14.81Z" }, ] [[package]] name = "pillow" -version = "11.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a5/26/0d95c04c868f6bdb0c447e3ee2de5564411845e36a858cfd63766bc7b563/pillow-11.0.0.tar.gz", hash = "sha256:72bacbaf24ac003fea9bff9837d1eedb6088758d41e100c1552930151f677739", size = 46737780 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/98/fb/a6ce6836bd7fd93fbf9144bf54789e02babc27403b50a9e1583ee877d6da/pillow-11.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:6619654954dc4936fcff82db8eb6401d3159ec6be81e33c6000dfd76ae189947", size = 3154708 }, - { url = "https://files.pythonhosted.org/packages/6a/1d/1f51e6e912d8ff316bb3935a8cda617c801783e0b998bf7a894e91d3bd4c/pillow-11.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b3c5ac4bed7519088103d9450a1107f76308ecf91d6dabc8a33a2fcfb18d0fba", size = 2979223 }, - { url = "https://files.pythonhosted.org/packages/90/83/e2077b0192ca8a9ef794dbb74700c7e48384706467067976c2a95a0f40a1/pillow-11.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a65149d8ada1055029fcb665452b2814fe7d7082fcb0c5bed6db851cb69b2086", size = 4183167 }, - { url = "https://files.pythonhosted.org/packages/0e/74/467af0146970a98349cdf39e9b79a6cc8a2e7558f2c01c28a7b6b85c5bda/pillow-11.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88a58d8ac0cc0e7f3a014509f0455248a76629ca9b604eca7dc5927cc593c5e9", size = 4283912 }, - { url = "https://files.pythonhosted.org/packages/85/b1/d95d4f7ca3a6c1ae120959605875a31a3c209c4e50f0029dc1a87566cf46/pillow-11.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:c26845094b1af3c91852745ae78e3ea47abf3dbcd1cf962f16b9a5fbe3ee8488", size = 4195815 }, - { url = "https://files.pythonhosted.org/packages/41/c3/94f33af0762ed76b5a237c5797e088aa57f2b7fa8ee7932d399087be66a8/pillow-11.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:1a61b54f87ab5786b8479f81c4b11f4d61702830354520837f8cc791ebba0f5f", size = 4366117 }, - { url = "https://files.pythonhosted.org/packages/ba/3c/443e7ef01f597497268899e1cca95c0de947c9bbf77a8f18b3c126681e5d/pillow-11.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:674629ff60030d144b7bca2b8330225a9b11c482ed408813924619c6f302fdbb", size = 4278607 }, - { url = "https://files.pythonhosted.org/packages/26/95/1495304448b0081e60c0c5d63f928ef48bb290acee7385804426fa395a21/pillow-11.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:598b4e238f13276e0008299bd2482003f48158e2b11826862b1eb2ad7c768b97", size = 4410685 }, - { url = "https://files.pythonhosted.org/packages/45/da/861e1df971ef0de9870720cb309ca4d553b26a9483ec9be3a7bf1de4a095/pillow-11.0.0-cp310-cp310-win32.whl", hash = "sha256:9a0f748eaa434a41fccf8e1ee7a3eed68af1b690e75328fd7a60af123c193b50", size = 2249185 }, - { url = "https://files.pythonhosted.org/packages/d5/4e/78f7c5202ea2a772a5ab05069c1b82503e6353cd79c7e474d4945f4b82c3/pillow-11.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:a5629742881bcbc1f42e840af185fd4d83a5edeb96475a575f4da50d6ede337c", size = 2566726 }, - { url = "https://files.pythonhosted.org/packages/77/e4/6e84eada35cbcc646fc1870f72ccfd4afacb0fae0c37ffbffe7f5dc24bf1/pillow-11.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:ee217c198f2e41f184f3869f3e485557296d505b5195c513b2bfe0062dc537f1", size = 2254585 }, - { url = "https://files.pythonhosted.org/packages/f0/eb/f7e21b113dd48a9c97d364e0915b3988c6a0b6207652f5a92372871b7aa4/pillow-11.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1c1d72714f429a521d8d2d018badc42414c3077eb187a59579f28e4270b4b0fc", size = 3154705 }, - { url = "https://files.pythonhosted.org/packages/25/b3/2b54a1d541accebe6bd8b1358b34ceb2c509f51cb7dcda8687362490da5b/pillow-11.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:499c3a1b0d6fc8213519e193796eb1a86a1be4b1877d678b30f83fd979811d1a", size = 2979222 }, - { url = "https://files.pythonhosted.org/packages/20/12/1a41eddad8265c5c19dda8fb6c269ce15ee25e0b9f8f26286e6202df6693/pillow-11.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8b2351c85d855293a299038e1f89db92a2f35e8d2f783489c6f0b2b5f3fe8a3", size = 4190220 }, - { url = "https://files.pythonhosted.org/packages/a9/9b/8a8c4d07d77447b7457164b861d18f5a31ae6418ef5c07f6f878fa09039a/pillow-11.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f4dba50cfa56f910241eb7f883c20f1e7b1d8f7d91c750cd0b318bad443f4d5", size = 4291399 }, - { url = "https://files.pythonhosted.org/packages/fc/e4/130c5fab4a54d3991129800dd2801feeb4b118d7630148cd67f0e6269d4c/pillow-11.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:5ddbfd761ee00c12ee1be86c9c0683ecf5bb14c9772ddbd782085779a63dd55b", size = 4202709 }, - { url = "https://files.pythonhosted.org/packages/39/63/b3fc299528d7df1f678b0666002b37affe6b8751225c3d9c12cf530e73ed/pillow-11.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:45c566eb10b8967d71bf1ab8e4a525e5a93519e29ea071459ce517f6b903d7fa", size = 4372556 }, - { url = "https://files.pythonhosted.org/packages/c6/a6/694122c55b855b586c26c694937d36bb8d3b09c735ff41b2f315c6e66a10/pillow-11.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b4fd7bd29610a83a8c9b564d457cf5bd92b4e11e79a4ee4716a63c959699b306", size = 4287187 }, - { url = "https://files.pythonhosted.org/packages/ba/a9/f9d763e2671a8acd53d29b1e284ca298bc10a595527f6be30233cdb9659d/pillow-11.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:cb929ca942d0ec4fac404cbf520ee6cac37bf35be479b970c4ffadf2b6a1cad9", size = 4418468 }, - { url = "https://files.pythonhosted.org/packages/6e/0e/b5cbad2621377f11313a94aeb44ca55a9639adabcaaa073597a1925f8c26/pillow-11.0.0-cp311-cp311-win32.whl", hash = "sha256:006bcdd307cc47ba43e924099a038cbf9591062e6c50e570819743f5607404f5", size = 2249249 }, - { url = "https://files.pythonhosted.org/packages/dc/83/1470c220a4ff06cd75fc609068f6605e567ea51df70557555c2ab6516b2c/pillow-11.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:52a2d8323a465f84faaba5236567d212c3668f2ab53e1c74c15583cf507a0291", size = 2566769 }, - { url = "https://files.pythonhosted.org/packages/52/98/def78c3a23acee2bcdb2e52005fb2810ed54305602ec1bfcfab2bda6f49f/pillow-11.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:16095692a253047fe3ec028e951fa4221a1f3ed3d80c397e83541a3037ff67c9", size = 2254611 }, - { url = "https://files.pythonhosted.org/packages/1c/a3/26e606ff0b2daaf120543e537311fa3ae2eb6bf061490e4fea51771540be/pillow-11.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2c0a187a92a1cb5ef2c8ed5412dd8d4334272617f532d4ad4de31e0495bd923", size = 3147642 }, - { url = "https://files.pythonhosted.org/packages/4f/d5/1caabedd8863526a6cfa44ee7a833bd97f945dc1d56824d6d76e11731939/pillow-11.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:084a07ef0821cfe4858fe86652fffac8e187b6ae677e9906e192aafcc1b69903", size = 2978999 }, - { url = "https://files.pythonhosted.org/packages/d9/ff/5a45000826a1aa1ac6874b3ec5a856474821a1b59d838c4f6ce2ee518fe9/pillow-11.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8069c5179902dcdce0be9bfc8235347fdbac249d23bd90514b7a47a72d9fecf4", size = 4196794 }, - { url = "https://files.pythonhosted.org/packages/9d/21/84c9f287d17180f26263b5f5c8fb201de0f88b1afddf8a2597a5c9fe787f/pillow-11.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f02541ef64077f22bf4924f225c0fd1248c168f86e4b7abdedd87d6ebaceab0f", size = 4300762 }, - { url = "https://files.pythonhosted.org/packages/84/39/63fb87cd07cc541438b448b1fed467c4d687ad18aa786a7f8e67b255d1aa/pillow-11.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:fcb4621042ac4b7865c179bb972ed0da0218a076dc1820ffc48b1d74c1e37fe9", size = 4210468 }, - { url = "https://files.pythonhosted.org/packages/7f/42/6e0f2c2d5c60f499aa29be14f860dd4539de322cd8fb84ee01553493fb4d/pillow-11.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:00177a63030d612148e659b55ba99527803288cea7c75fb05766ab7981a8c1b7", size = 4381824 }, - { url = "https://files.pythonhosted.org/packages/31/69/1ef0fb9d2f8d2d114db982b78ca4eeb9db9a29f7477821e160b8c1253f67/pillow-11.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8853a3bf12afddfdf15f57c4b02d7ded92c7a75a5d7331d19f4f9572a89c17e6", size = 4296436 }, - { url = "https://files.pythonhosted.org/packages/44/ea/dad2818c675c44f6012289a7c4f46068c548768bc6c7f4e8c4ae5bbbc811/pillow-11.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3107c66e43bda25359d5ef446f59c497de2b5ed4c7fdba0894f8d6cf3822dafc", size = 4429714 }, - { url = "https://files.pythonhosted.org/packages/af/3a/da80224a6eb15bba7a0dcb2346e2b686bb9bf98378c0b4353cd88e62b171/pillow-11.0.0-cp312-cp312-win32.whl", hash = "sha256:86510e3f5eca0ab87429dd77fafc04693195eec7fd6a137c389c3eeb4cfb77c6", size = 2249631 }, - { url = "https://files.pythonhosted.org/packages/57/97/73f756c338c1d86bb802ee88c3cab015ad7ce4b838f8a24f16b676b1ac7c/pillow-11.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:8ec4a89295cd6cd4d1058a5e6aec6bf51e0eaaf9714774e1bfac7cfc9051db47", size = 2567533 }, - { url = "https://files.pythonhosted.org/packages/0b/30/2b61876e2722374558b871dfbfcbe4e406626d63f4f6ed92e9c8e24cac37/pillow-11.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:27a7860107500d813fcd203b4ea19b04babe79448268403172782754870dac25", size = 2254890 }, - { url = "https://files.pythonhosted.org/packages/36/57/42a4dd825eab762ba9e690d696d894ba366e06791936056e26e099398cda/pillow-11.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1187739620f2b365de756ce086fdb3604573337cc28a0d3ac4a01ab6b2d2a6d2", size = 3119239 }, - { url = "https://files.pythonhosted.org/packages/98/f7/25f9f9e368226a1d6cf3507081a1a7944eddd3ca7821023377043f5a83c8/pillow-11.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fbbcb7b57dc9c794843e3d1258c0fbf0f48656d46ffe9e09b63bbd6e8cd5d0a2", size = 2950803 }, - { url = "https://files.pythonhosted.org/packages/59/01/98ead48a6c2e31e6185d4c16c978a67fe3ccb5da5c2ff2ba8475379bb693/pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d203af30149ae339ad1b4f710d9844ed8796e97fda23ffbc4cc472968a47d0b", size = 3281098 }, - { url = "https://files.pythonhosted.org/packages/51/c0/570255b2866a0e4d500a14f950803a2ec273bac7badc43320120b9262450/pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21a0d3b115009ebb8ac3d2ebec5c2982cc693da935f4ab7bb5c8ebe2f47d36f2", size = 3323665 }, - { url = "https://files.pythonhosted.org/packages/0e/75/689b4ec0483c42bfc7d1aacd32ade7a226db4f4fac57c6fdcdf90c0731e3/pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:73853108f56df97baf2bb8b522f3578221e56f646ba345a372c78326710d3830", size = 3310533 }, - { url = "https://files.pythonhosted.org/packages/3d/30/38bd6149cf53da1db4bad304c543ade775d225961c4310f30425995cb9ec/pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e58876c91f97b0952eb766123bfef372792ab3f4e3e1f1a2267834c2ab131734", size = 3414886 }, - { url = "https://files.pythonhosted.org/packages/ec/3d/c32a51d848401bd94cabb8767a39621496491ee7cd5199856b77da9b18ad/pillow-11.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:224aaa38177597bb179f3ec87eeefcce8e4f85e608025e9cfac60de237ba6316", size = 2567508 }, +version = "11.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/0d/d0d6dea55cd152ce3d6767bb38a8fc10e33796ba4ba210cbab9354b6d238/pillow-11.3.0.tar.gz", hash = "sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523", size = 47113069, upload-time = "2025-07-01T09:16:30.666Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/26/77f8ed17ca4ffd60e1dcd220a6ec6d71210ba398cfa33a13a1cd614c5613/pillow-11.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1cd110edf822773368b396281a2293aeb91c90a2db00d78ea43e7e861631b722", size = 5316531, upload-time = "2025-07-01T09:13:59.203Z" }, + { url = "https://files.pythonhosted.org/packages/cb/39/ee475903197ce709322a17a866892efb560f57900d9af2e55f86db51b0a5/pillow-11.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9c412fddd1b77a75aa904615ebaa6001f169b26fd467b4be93aded278266b288", size = 4686560, upload-time = "2025-07-01T09:14:01.101Z" }, + { url = "https://files.pythonhosted.org/packages/d5/90/442068a160fd179938ba55ec8c97050a612426fae5ec0a764e345839f76d/pillow-11.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d1aa4de119a0ecac0a34a9c8bde33f34022e2e8f99104e47a3ca392fd60e37d", size = 5870978, upload-time = "2025-07-03T13:09:55.638Z" }, + { url = "https://files.pythonhosted.org/packages/13/92/dcdd147ab02daf405387f0218dcf792dc6dd5b14d2573d40b4caeef01059/pillow-11.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:91da1d88226663594e3f6b4b8c3c8d85bd504117d043740a8e0ec449087cc494", size = 7641168, upload-time = "2025-07-03T13:10:00.37Z" }, + { url = "https://files.pythonhosted.org/packages/6e/db/839d6ba7fd38b51af641aa904e2960e7a5644d60ec754c046b7d2aee00e5/pillow-11.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:643f189248837533073c405ec2f0bb250ba54598cf80e8c1e043381a60632f58", size = 5973053, upload-time = "2025-07-01T09:14:04.491Z" }, + { url = "https://files.pythonhosted.org/packages/f2/2f/d7675ecae6c43e9f12aa8d58b6012683b20b6edfbdac7abcb4e6af7a3784/pillow-11.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:106064daa23a745510dabce1d84f29137a37224831d88eb4ce94bb187b1d7e5f", size = 6640273, upload-time = "2025-07-01T09:14:06.235Z" }, + { url = "https://files.pythonhosted.org/packages/45/ad/931694675ede172e15b2ff03c8144a0ddaea1d87adb72bb07655eaffb654/pillow-11.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cd8ff254faf15591e724dc7c4ddb6bf4793efcbe13802a4ae3e863cd300b493e", size = 6082043, upload-time = "2025-07-01T09:14:07.978Z" }, + { url = "https://files.pythonhosted.org/packages/3a/04/ba8f2b11fc80d2dd462d7abec16351b45ec99cbbaea4387648a44190351a/pillow-11.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:932c754c2d51ad2b2271fd01c3d121daaa35e27efae2a616f77bf164bc0b3e94", size = 6715516, upload-time = "2025-07-01T09:14:10.233Z" }, + { url = "https://files.pythonhosted.org/packages/48/59/8cd06d7f3944cc7d892e8533c56b0acb68399f640786313275faec1e3b6f/pillow-11.3.0-cp311-cp311-win32.whl", hash = "sha256:b4b8f3efc8d530a1544e5962bd6b403d5f7fe8b9e08227c6b255f98ad82b4ba0", size = 6274768, upload-time = "2025-07-01T09:14:11.921Z" }, + { url = "https://files.pythonhosted.org/packages/f1/cc/29c0f5d64ab8eae20f3232da8f8571660aa0ab4b8f1331da5c2f5f9a938e/pillow-11.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:1a992e86b0dd7aeb1f053cd506508c0999d710a8f07b4c791c63843fc6a807ac", size = 6986055, upload-time = "2025-07-01T09:14:13.623Z" }, + { url = "https://files.pythonhosted.org/packages/c6/df/90bd886fabd544c25addd63e5ca6932c86f2b701d5da6c7839387a076b4a/pillow-11.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:30807c931ff7c095620fe04448e2c2fc673fcbb1ffe2a7da3fb39613489b1ddd", size = 2423079, upload-time = "2025-07-01T09:14:15.268Z" }, + { url = "https://files.pythonhosted.org/packages/40/fe/1bc9b3ee13f68487a99ac9529968035cca2f0a51ec36892060edcc51d06a/pillow-11.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4", size = 5278800, upload-time = "2025-07-01T09:14:17.648Z" }, + { url = "https://files.pythonhosted.org/packages/2c/32/7e2ac19b5713657384cec55f89065fb306b06af008cfd87e572035b27119/pillow-11.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69", size = 4686296, upload-time = "2025-07-01T09:14:19.828Z" }, + { url = "https://files.pythonhosted.org/packages/8e/1e/b9e12bbe6e4c2220effebc09ea0923a07a6da1e1f1bfbc8d7d29a01ce32b/pillow-11.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb76541cba2f958032d79d143b98a3a6b3ea87f0959bbe256c0b5e416599fd5d", size = 5871726, upload-time = "2025-07-03T13:10:04.448Z" }, + { url = "https://files.pythonhosted.org/packages/8d/33/e9200d2bd7ba00dc3ddb78df1198a6e80d7669cce6c2bdbeb2530a74ec58/pillow-11.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:67172f2944ebba3d4a7b54f2e95c786a3a50c21b88456329314caaa28cda70f6", size = 7644652, upload-time = "2025-07-03T13:10:10.391Z" }, + { url = "https://files.pythonhosted.org/packages/41/f1/6f2427a26fc683e00d985bc391bdd76d8dd4e92fac33d841127eb8fb2313/pillow-11.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7", size = 5977787, upload-time = "2025-07-01T09:14:21.63Z" }, + { url = "https://files.pythonhosted.org/packages/e4/c9/06dd4a38974e24f932ff5f98ea3c546ce3f8c995d3f0985f8e5ba48bba19/pillow-11.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024", size = 6645236, upload-time = "2025-07-01T09:14:23.321Z" }, + { url = "https://files.pythonhosted.org/packages/40/e7/848f69fb79843b3d91241bad658e9c14f39a32f71a301bcd1d139416d1be/pillow-11.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809", size = 6086950, upload-time = "2025-07-01T09:14:25.237Z" }, + { url = "https://files.pythonhosted.org/packages/0b/1a/7cff92e695a2a29ac1958c2a0fe4c0b2393b60aac13b04a4fe2735cad52d/pillow-11.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6be31e3fc9a621e071bc17bb7de63b85cbe0bfae91bb0363c893cbe67247780d", size = 6723358, upload-time = "2025-07-01T09:14:27.053Z" }, + { url = "https://files.pythonhosted.org/packages/26/7d/73699ad77895f69edff76b0f332acc3d497f22f5d75e5360f78cbcaff248/pillow-11.3.0-cp312-cp312-win32.whl", hash = "sha256:7b161756381f0918e05e7cb8a371fff367e807770f8fe92ecb20d905d0e1c149", size = 6275079, upload-time = "2025-07-01T09:14:30.104Z" }, + { url = "https://files.pythonhosted.org/packages/8c/ce/e7dfc873bdd9828f3b6e5c2bbb74e47a98ec23cc5c74fc4e54462f0d9204/pillow-11.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a6444696fce635783440b7f7a9fc24b3ad10a9ea3f0ab66c5905be1c19ccf17d", size = 6986324, upload-time = "2025-07-01T09:14:31.899Z" }, + { url = "https://files.pythonhosted.org/packages/16/8f/b13447d1bf0b1f7467ce7d86f6e6edf66c0ad7cf44cf5c87a37f9bed9936/pillow-11.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:2aceea54f957dd4448264f9bf40875da0415c83eb85f55069d89c0ed436e3542", size = 2423067, upload-time = "2025-07-01T09:14:33.709Z" }, + { url = "https://files.pythonhosted.org/packages/1e/93/0952f2ed8db3a5a4c7a11f91965d6184ebc8cd7cbb7941a260d5f018cd2d/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd", size = 2128328, upload-time = "2025-07-01T09:14:35.276Z" }, + { url = "https://files.pythonhosted.org/packages/4b/e8/100c3d114b1a0bf4042f27e0f87d2f25e857e838034e98ca98fe7b8c0a9c/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8", size = 2170652, upload-time = "2025-07-01T09:14:37.203Z" }, + { url = "https://files.pythonhosted.org/packages/aa/86/3f758a28a6e381758545f7cdb4942e1cb79abd271bea932998fc0db93cb6/pillow-11.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f", size = 2227443, upload-time = "2025-07-01T09:14:39.344Z" }, + { url = "https://files.pythonhosted.org/packages/01/f4/91d5b3ffa718df2f53b0dc109877993e511f4fd055d7e9508682e8aba092/pillow-11.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c", size = 5278474, upload-time = "2025-07-01T09:14:41.843Z" }, + { url = "https://files.pythonhosted.org/packages/f9/0e/37d7d3eca6c879fbd9dba21268427dffda1ab00d4eb05b32923d4fbe3b12/pillow-11.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd", size = 4686038, upload-time = "2025-07-01T09:14:44.008Z" }, + { url = "https://files.pythonhosted.org/packages/ff/b0/3426e5c7f6565e752d81221af9d3676fdbb4f352317ceafd42899aaf5d8a/pillow-11.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e", size = 5864407, upload-time = "2025-07-03T13:10:15.628Z" }, + { url = "https://files.pythonhosted.org/packages/fc/c1/c6c423134229f2a221ee53f838d4be9d82bab86f7e2f8e75e47b6bf6cd77/pillow-11.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1", size = 7639094, upload-time = "2025-07-03T13:10:21.857Z" }, + { url = "https://files.pythonhosted.org/packages/ba/c9/09e6746630fe6372c67c648ff9deae52a2bc20897d51fa293571977ceb5d/pillow-11.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805", size = 5973503, upload-time = "2025-07-01T09:14:45.698Z" }, + { url = "https://files.pythonhosted.org/packages/d5/1c/a2a29649c0b1983d3ef57ee87a66487fdeb45132df66ab30dd37f7dbe162/pillow-11.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8", size = 6642574, upload-time = "2025-07-01T09:14:47.415Z" }, + { url = "https://files.pythonhosted.org/packages/36/de/d5cc31cc4b055b6c6fd990e3e7f0f8aaf36229a2698501bcb0cdf67c7146/pillow-11.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2", size = 6084060, upload-time = "2025-07-01T09:14:49.636Z" }, + { url = "https://files.pythonhosted.org/packages/d5/ea/502d938cbaeec836ac28a9b730193716f0114c41325db428e6b280513f09/pillow-11.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b", size = 6721407, upload-time = "2025-07-01T09:14:51.962Z" }, + { url = "https://files.pythonhosted.org/packages/45/9c/9c5e2a73f125f6cbc59cc7087c8f2d649a7ae453f83bd0362ff7c9e2aee2/pillow-11.3.0-cp313-cp313-win32.whl", hash = "sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3", size = 6273841, upload-time = "2025-07-01T09:14:54.142Z" }, + { url = "https://files.pythonhosted.org/packages/23/85/397c73524e0cd212067e0c969aa245b01d50183439550d24d9f55781b776/pillow-11.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51", size = 6978450, upload-time = "2025-07-01T09:14:56.436Z" }, + { url = "https://files.pythonhosted.org/packages/17/d2/622f4547f69cd173955194b78e4d19ca4935a1b0f03a302d655c9f6aae65/pillow-11.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580", size = 2423055, upload-time = "2025-07-01T09:14:58.072Z" }, + { url = "https://files.pythonhosted.org/packages/dd/80/a8a2ac21dda2e82480852978416cfacd439a4b490a501a288ecf4fe2532d/pillow-11.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e", size = 5281110, upload-time = "2025-07-01T09:14:59.79Z" }, + { url = "https://files.pythonhosted.org/packages/44/d6/b79754ca790f315918732e18f82a8146d33bcd7f4494380457ea89eb883d/pillow-11.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d", size = 4689547, upload-time = "2025-07-01T09:15:01.648Z" }, + { url = "https://files.pythonhosted.org/packages/49/20/716b8717d331150cb00f7fdd78169c01e8e0c219732a78b0e59b6bdb2fd6/pillow-11.3.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced", size = 5901554, upload-time = "2025-07-03T13:10:27.018Z" }, + { url = "https://files.pythonhosted.org/packages/74/cf/a9f3a2514a65bb071075063a96f0a5cf949c2f2fce683c15ccc83b1c1cab/pillow-11.3.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c", size = 7669132, upload-time = "2025-07-03T13:10:33.01Z" }, + { url = "https://files.pythonhosted.org/packages/98/3c/da78805cbdbee9cb43efe8261dd7cc0b4b93f2ac79b676c03159e9db2187/pillow-11.3.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8", size = 6005001, upload-time = "2025-07-01T09:15:03.365Z" }, + { url = "https://files.pythonhosted.org/packages/6c/fa/ce044b91faecf30e635321351bba32bab5a7e034c60187fe9698191aef4f/pillow-11.3.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59", size = 6668814, upload-time = "2025-07-01T09:15:05.655Z" }, + { url = "https://files.pythonhosted.org/packages/7b/51/90f9291406d09bf93686434f9183aba27b831c10c87746ff49f127ee80cb/pillow-11.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe", size = 6113124, upload-time = "2025-07-01T09:15:07.358Z" }, + { url = "https://files.pythonhosted.org/packages/cd/5a/6fec59b1dfb619234f7636d4157d11fb4e196caeee220232a8d2ec48488d/pillow-11.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c", size = 6747186, upload-time = "2025-07-01T09:15:09.317Z" }, + { url = "https://files.pythonhosted.org/packages/49/6b/00187a044f98255225f172de653941e61da37104a9ea60e4f6887717e2b5/pillow-11.3.0-cp313-cp313t-win32.whl", hash = "sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788", size = 6277546, upload-time = "2025-07-01T09:15:11.311Z" }, + { url = "https://files.pythonhosted.org/packages/e8/5c/6caaba7e261c0d75bab23be79f1d06b5ad2a2ae49f028ccec801b0e853d6/pillow-11.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31", size = 6985102, upload-time = "2025-07-01T09:15:13.164Z" }, + { url = "https://files.pythonhosted.org/packages/f3/7e/b623008460c09a0cb38263c93b828c666493caee2eb34ff67f778b87e58c/pillow-11.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e", size = 2424803, upload-time = "2025-07-01T09:15:15.695Z" }, + { url = "https://files.pythonhosted.org/packages/9e/e3/6fa84033758276fb31da12e5fb66ad747ae83b93c67af17f8c6ff4cc8f34/pillow-11.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7c8ec7a017ad1bd562f93dbd8505763e688d388cde6e4a010ae1486916e713e6", size = 5270566, upload-time = "2025-07-01T09:16:19.801Z" }, + { url = "https://files.pythonhosted.org/packages/5b/ee/e8d2e1ab4892970b561e1ba96cbd59c0d28cf66737fc44abb2aec3795a4e/pillow-11.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9ab6ae226de48019caa8074894544af5b53a117ccb9d3b3dcb2871464c829438", size = 4654618, upload-time = "2025-07-01T09:16:21.818Z" }, + { url = "https://files.pythonhosted.org/packages/f2/6d/17f80f4e1f0761f02160fc433abd4109fa1548dcfdca46cfdadaf9efa565/pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fe27fb049cdcca11f11a7bfda64043c37b30e6b91f10cb5bab275806c32f6ab3", size = 4874248, upload-time = "2025-07-03T13:11:20.738Z" }, + { url = "https://files.pythonhosted.org/packages/de/5f/c22340acd61cef960130585bbe2120e2fd8434c214802f07e8c03596b17e/pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:465b9e8844e3c3519a983d58b80be3f668e2a7a5db97f2784e7079fbc9f9822c", size = 6583963, upload-time = "2025-07-03T13:11:26.283Z" }, + { url = "https://files.pythonhosted.org/packages/31/5e/03966aedfbfcbb4d5f8aa042452d3361f325b963ebbadddac05b122e47dd/pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5418b53c0d59b3824d05e029669efa023bbef0f3e92e75ec8428f3799487f361", size = 4957170, upload-time = "2025-07-01T09:16:23.762Z" }, + { url = "https://files.pythonhosted.org/packages/cc/2d/e082982aacc927fc2cab48e1e731bdb1643a1406acace8bed0900a61464e/pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:504b6f59505f08ae014f724b6207ff6222662aab5cc9542577fb084ed0676ac7", size = 5581505, upload-time = "2025-07-01T09:16:25.593Z" }, + { url = "https://files.pythonhosted.org/packages/34/e7/ae39f538fd6844e982063c3a5e4598b8ced43b9633baa3a85ef33af8c05c/pillow-11.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c84d689db21a1c397d001aa08241044aa2069e7587b398c8cc63020390b1c1b8", size = 6984598, upload-time = "2025-07-01T09:16:27.732Z" }, ] [[package]] name = "platformdirs" -version = "4.3.6" +version = "4.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/13/fc/128cc9cb8f03208bdbf93d3aa862e16d376844a14f9a0ce5cf4507372de4/platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", size = 21302 } +sdist = { url = "https://files.pythonhosted.org/packages/23/e8/21db9c9987b0e728855bd57bff6984f67952bea55d6f75e055c46b5383e8/platformdirs-4.4.0.tar.gz", hash = "sha256:ca753cf4d81dc309bc67b0ea38fd15dc97bc30ce419a7f58d13eb3bf14c4febf", size = 21634, upload-time = "2025-08-26T14:32:04.268Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb", size = 18439 }, + { url = "https://files.pythonhosted.org/packages/40/4b/2028861e724d3bd36227adfa20d3fd24c3fc6d52032f4a93c133be5d17ce/platformdirs-4.4.0-py3-none-any.whl", hash = "sha256:abd01743f24e5287cd7a5db3752faf1a2d65353f38ec26d98e25a6db65958c85", size = 18654, upload-time = "2025-08-26T14:32:02.735Z" }, ] [[package]] name = "pluggy" -version = "1.5.0" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "polyround" +version = "0.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 } +dependencies = [ + { name = "numpy" }, + { name = "optlang" }, + { name = "pandas" }, + { name = "scipy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4a/56/5b05ab0cbfe77dcf792e82ce1e1311461776c5413a99342f141641d7804a/polyround-0.4.0.tar.gz", hash = "sha256:e7312f0a8c435827627ac05d873969168f31373e5136f75e66c5a4d9e06f8833", size = 38570, upload-time = "2025-08-12T14:09:18.38Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, + { url = "https://files.pythonhosted.org/packages/2d/f1/9b10002d4114a08a807ce69cc1136eea62e32cbc9da2a24a12357c3201b7/polyround-0.4.0-py3-none-any.whl", hash = "sha256:4ac6a2a4b31f5ac83b32ee95e276fb6ec31a76ec0719d80ba4160c3f6bfa9cd3", size = 43357, upload-time = "2025-08-12T14:09:17.434Z" }, ] [[package]] name = "pox" -version = "0.3.5" +version = "0.3.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2e/0d/f2eb94b4d1358a60f3539a6abcbbd757fbcb78538fe8d4cfa49850356ccf/pox-0.3.5.tar.gz", hash = "sha256:8120ee4c94e950e6e0483e050a4f0e56076e590ba0a9add19524c254bd23c2d1", size = 119452 } +sdist = { url = "https://files.pythonhosted.org/packages/56/99/42670d273fd598a6fe98c8b2f593ee425b29e44f2d1a61ff622031204ccd/pox-0.3.6.tar.gz", hash = "sha256:84eeed39600159a62804aacfc00e353edeaae67d8c647ccaaab73a6efed3f605", size = 119393, upload-time = "2025-04-16T00:05:49.811Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1d/4c/490d8f7825f38fa77bff188c568163f222d01f6c6d76f574429135edfc49/pox-0.3.5-py3-none-any.whl", hash = "sha256:9e82bcc9e578b43e80a99cad80f0d8f44f4d424f0ee4ee8d4db27260a6aa365a", size = 29492 }, + { url = "https://files.pythonhosted.org/packages/0d/c2/6435789c26661bef699868ee54d2763aea636a1ed21ec8e350b1f9f65888/pox-0.3.6-py3-none-any.whl", hash = "sha256:d48654d0a3dca0c9c02dccae54a53c3870286a5217ad306b2bd94f84e008bc1b", size = 29495, upload-time = "2025-04-16T00:05:48.319Z" }, ] [[package]] name = "ppft" -version = "1.7.6.9" +version = "1.7.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/46/9e9f2ae7e8e284acbde6ab36f7f4a35b273519a60c0ed419af2da780d49f/ppft-1.7.7.tar.gz", hash = "sha256:f3f77448cfe24c2b8d2296b6d8732280b25041a3f3e1f551856c6451d3e01b96", size = 136272, upload-time = "2025-04-16T01:47:40.925Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5b/23/6aef7c24f4ee6f765aeaaaa3bf24cfdb0730a20336a02b1a061d227d84be/ppft-1.7.7-py3-none-any.whl", hash = "sha256:fb7524db110682de886b4bb5b08f7bf6a38940566074ef2f62521cbbd3864676", size = 56764, upload-time = "2025-04-16T01:47:39.453Z" }, +] + +[[package]] +name = "pre-commit" +version = "4.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2b/06/305532df3e1b0c601f60854b6e080991835809d077934cf41976d0f224ce/ppft-1.7.6.9.tar.gz", hash = "sha256:73161c67474ea9d81d04bcdad166d399cff3f084d5d2dc21ebdd46c075bbc265", size = 136395 } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ff/29/7cf5bbc236333876e4b41f56e06857a87937ce4bf91e117a6991a2dbb02a/pre_commit-4.3.0.tar.gz", hash = "sha256:499fe450cc9d42e9d58e606262795ecb64dd05438943c62b66f6a8673da30b16", size = 193792, upload-time = "2025-08-09T18:56:14.651Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/02/b3/45a04dabc39d93ad4836d99625e7c5350257b48e9ae2c5b701f3d5da6960/ppft-1.7.6.9-py3-none-any.whl", hash = "sha256:dab36548db5ca3055067fbe6b1a17db5fee29f3c366c579a9a27cebb52ed96f0", size = 56792 }, + { url = "https://files.pythonhosted.org/packages/5b/a5/987a405322d78a73b66e39e4a90e4ef156fd7141bf71df987e50717c321b/pre_commit-4.3.0-py2.py3-none-any.whl", hash = "sha256:2b0747ad7e6e967169136edffee14c16e148a778a54e4f967921aa1ebf2308d8", size = 220965, upload-time = "2025-08-09T18:56:13.192Z" }, ] [[package]] name = "prometheus-client" -version = "0.21.1" +version = "0.22.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/62/14/7d0f567991f3a9af8d1cd4f619040c93b68f09a02b6d0b6ab1b2d1ded5fe/prometheus_client-0.21.1.tar.gz", hash = "sha256:252505a722ac04b0456be05c05f75f45d760c2911ffc45f2a06bcaed9f3ae3fb", size = 78551 } +sdist = { url = "https://files.pythonhosted.org/packages/5e/cf/40dde0a2be27cc1eb41e333d1a674a74ce8b8b0457269cc640fd42b07cf7/prometheus_client-0.22.1.tar.gz", hash = "sha256:190f1331e783cf21eb60bca559354e0a4d4378facecf78f5428c39b675d20d28", size = 69746, upload-time = "2025-06-02T14:29:01.152Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ff/c2/ab7d37426c179ceb9aeb109a85cda8948bb269b7561a0be870cc656eefe4/prometheus_client-0.21.1-py3-none-any.whl", hash = "sha256:594b45c410d6f4f8888940fe80b5cc2521b305a1fafe1c58609ef715a001f301", size = 54682 }, + { url = "https://files.pythonhosted.org/packages/32/ae/ec06af4fe3ee72d16973474f122541746196aaa16cea6f66d18b963c6177/prometheus_client-0.22.1-py3-none-any.whl", hash = "sha256:cca895342e308174341b2cbf99a56bef291fbc0ef7b9e5412a0f26d653ba7094", size = 58694, upload-time = "2025-06-02T14:29:00.068Z" }, ] [[package]] name = "prompt-toolkit" -version = "3.0.36" +version = "3.0.52" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "wcwidth" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fb/93/180be2342f89f16543ec4eb3f25083b5b84eba5378f68efff05409fb39a9/prompt_toolkit-3.0.36.tar.gz", hash = "sha256:3e163f254bef5a03b146397d7c1963bd3e2812f0964bb9a24e6ec761fd28db63", size = 423863 } +sdist = { url = "https://files.pythonhosted.org/packages/a1/96/06e01a7b38dce6fe1db213e061a4602dd6032a8a97ef6c1a862537732421/prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855", size = 434198, upload-time = "2025-08-27T15:24:02.057Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/eb/37/791f1a6edd13c61cac85282368aa68cb0f3f164440fdf60032f2cc6ca34e/prompt_toolkit-3.0.36-py3-none-any.whl", hash = "sha256:aa64ad242a462c5ff0363a7b9cfe696c20d55d9fc60c11fd8e632d064804d305", size = 386414 }, + { url = "https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955", size = 391431, upload-time = "2025-08-27T15:23:59.498Z" }, ] [[package]] name = "psutil" -version = "6.1.0" +version = "7.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/26/10/2a30b13c61e7cf937f4adf90710776b7918ed0a9c434e2c38224732af310/psutil-6.1.0.tar.gz", hash = "sha256:353815f59a7f64cdaca1c0307ee13558a0512f6db064e92fe833784f08539c7a", size = 508565 } +sdist = { url = "https://files.pythonhosted.org/packages/2a/80/336820c1ad9286a4ded7e845b2eccfcb27851ab8ac6abece774a6ff4d3de/psutil-7.0.0.tar.gz", hash = "sha256:7be9c3eba38beccb6495ea33afd982a44074b78f28c434a1f51cc07fd315c456", size = 497003, upload-time = "2025-02-13T21:54:07.946Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/01/9e/8be43078a171381953cfee33c07c0d628594b5dbfc5157847b85022c2c1b/psutil-6.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6e2dcd475ce8b80522e51d923d10c7871e45f20918e027ab682f94f1c6351688", size = 247762 }, - { url = "https://files.pythonhosted.org/packages/1d/cb/313e80644ea407f04f6602a9e23096540d9dc1878755f3952ea8d3d104be/psutil-6.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0895b8414afafc526712c498bd9de2b063deaac4021a3b3c34566283464aff8e", size = 248777 }, - { url = "https://files.pythonhosted.org/packages/65/8e/bcbe2025c587b5d703369b6a75b65d41d1367553da6e3f788aff91eaf5bd/psutil-6.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dcbfce5d89f1d1f2546a2090f4fcf87c7f669d1d90aacb7d7582addece9fb38", size = 284259 }, - { url = "https://files.pythonhosted.org/packages/58/4d/8245e6f76a93c98aab285a43ea71ff1b171bcd90c9d238bf81f7021fb233/psutil-6.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:498c6979f9c6637ebc3a73b3f87f9eb1ec24e1ce53a7c5173b8508981614a90b", size = 287255 }, - { url = "https://files.pythonhosted.org/packages/27/c2/d034856ac47e3b3cdfa9720d0e113902e615f4190d5d1bdb8df4b2015fb2/psutil-6.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d905186d647b16755a800e7263d43df08b790d709d575105d419f8b6ef65423a", size = 288804 }, - { url = "https://files.pythonhosted.org/packages/ea/55/5389ed243c878725feffc0d6a3bc5ef6764312b6fc7c081faaa2cfa7ef37/psutil-6.1.0-cp37-abi3-win32.whl", hash = "sha256:1ad45a1f5d0b608253b11508f80940985d1d0c8f6111b5cb637533a0e6ddc13e", size = 250386 }, - { url = "https://files.pythonhosted.org/packages/11/91/87fa6f060e649b1e1a7b19a4f5869709fbf750b7c8c262ee776ec32f3028/psutil-6.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:a8fb3752b491d246034fa4d279ff076501588ce8cbcdbb62c32fd7a377d996be", size = 254228 }, + { url = "https://files.pythonhosted.org/packages/ed/e6/2d26234410f8b8abdbf891c9da62bee396583f713fb9f3325a4760875d22/psutil-7.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:101d71dc322e3cffd7cea0650b09b3d08b8e7c4109dd6809fe452dfd00e58b25", size = 238051, upload-time = "2025-02-13T21:54:12.36Z" }, + { url = "https://files.pythonhosted.org/packages/04/8b/30f930733afe425e3cbfc0e1468a30a18942350c1a8816acfade80c005c4/psutil-7.0.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:39db632f6bb862eeccf56660871433e111b6ea58f2caea825571951d4b6aa3da", size = 239535, upload-time = "2025-02-13T21:54:16.07Z" }, + { url = "https://files.pythonhosted.org/packages/2a/ed/d362e84620dd22876b55389248e522338ed1bf134a5edd3b8231d7207f6d/psutil-7.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fcee592b4c6f146991ca55919ea3d1f8926497a713ed7faaf8225e174581e91", size = 275004, upload-time = "2025-02-13T21:54:18.662Z" }, + { url = "https://files.pythonhosted.org/packages/bf/b9/b0eb3f3cbcb734d930fdf839431606844a825b23eaf9a6ab371edac8162c/psutil-7.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b1388a4f6875d7e2aff5c4ca1cc16c545ed41dd8bb596cefea80111db353a34", size = 277986, upload-time = "2025-02-13T21:54:21.811Z" }, + { url = "https://files.pythonhosted.org/packages/eb/a2/709e0fe2f093556c17fbafda93ac032257242cabcc7ff3369e2cb76a97aa/psutil-7.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5f098451abc2828f7dc6b58d44b532b22f2088f4999a937557b603ce72b1993", size = 279544, upload-time = "2025-02-13T21:54:24.68Z" }, + { url = "https://files.pythonhosted.org/packages/50/e6/eecf58810b9d12e6427369784efe814a1eec0f492084ce8eb8f4d89d6d61/psutil-7.0.0-cp37-abi3-win32.whl", hash = "sha256:ba3fcef7523064a6c9da440fc4d6bd07da93ac726b5733c29027d7dc95b39d99", size = 241053, upload-time = "2025-02-13T21:54:34.31Z" }, + { url = "https://files.pythonhosted.org/packages/50/1b/6921afe68c74868b4c9fa424dad3be35b095e16687989ebbb50ce4fceb7c/psutil-7.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:4cf3d4eb1aa9b348dec30105c55cd9b7d4629285735a102beb4441e38db90553", size = 244885, upload-time = "2025-02-13T21:54:37.486Z" }, ] [[package]] name = "ptyprocess" version = "0.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762 } +sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762, upload-time = "2020-12-28T15:15:30.155Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993 }, + { url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993, upload-time = "2020-12-28T15:15:28.35Z" }, ] [[package]] name = "pure-eval" version = "0.2.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42", size = 19752 } +sdist = { url = "https://files.pythonhosted.org/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42", size = 19752, upload-time = "2024-07-21T12:58:21.801Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842 }, + { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842, upload-time = "2024-07-21T12:58:20.04Z" }, ] [[package]] name = "pycparser" version = "2.22" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736 } +sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736, upload-time = "2024-03-30T13:22:22.564Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552 }, + { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552, upload-time = "2024-03-30T13:22:20.476Z" }, ] [[package]] name = "pydantic" -version = "2.10.3" +version = "2.11.7" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, { name = "pydantic-core" }, { name = "typing-extensions" }, + { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/45/0f/27908242621b14e649a84e62b133de45f84c255eecb350ab02979844a788/pydantic-2.10.3.tar.gz", hash = "sha256:cb5ac360ce894ceacd69c403187900a02c4b20b693a9dd1d643e1effab9eadf9", size = 786486 } +sdist = { url = "https://files.pythonhosted.org/packages/00/dd/4325abf92c39ba8623b5af936ddb36ffcfe0beae70405d456ab1fb2f5b8c/pydantic-2.11.7.tar.gz", hash = "sha256:d989c3c6cb79469287b1569f7447a17848c998458d49ebe294e975b9baf0f0db", size = 788350, upload-time = "2025-06-14T08:33:17.137Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/62/51/72c18c55cf2f46ff4f91ebcc8f75aa30f7305f3d726be3f4ebffb4ae972b/pydantic-2.10.3-py3-none-any.whl", hash = "sha256:be04d85bbc7b65651c5f8e6b9976ed9c6f41782a55524cef079a34a0bb82144d", size = 456997 }, + { url = "https://files.pythonhosted.org/packages/6a/c0/ec2b1c8712ca690e5d61979dee872603e92b8a32f94cc1b72d53beab008a/pydantic-2.11.7-py3-none-any.whl", hash = "sha256:dde5df002701f6de26248661f6835bbe296a47bf73990135c7d07ce741b9623b", size = 444782, upload-time = "2025-06-14T08:33:14.905Z" }, ] [[package]] name = "pydantic-core" -version = "2.27.1" +version = "2.33.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a6/9f/7de1f19b6aea45aeb441838782d68352e71bfa98ee6fa048d5041991b33e/pydantic_core-2.27.1.tar.gz", hash = "sha256:62a763352879b84aa31058fc931884055fd75089cccbd9d58bb6afd01141b235", size = 412785 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6e/ce/60fd96895c09738648c83f3f00f595c807cb6735c70d3306b548cc96dd49/pydantic_core-2.27.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:71a5e35c75c021aaf400ac048dacc855f000bdfed91614b4a726f7432f1f3d6a", size = 1897984 }, - { url = "https://files.pythonhosted.org/packages/fd/b9/84623d6b6be98cc209b06687d9bca5a7b966ffed008d15225dd0d20cce2e/pydantic_core-2.27.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f82d068a2d6ecfc6e054726080af69a6764a10015467d7d7b9f66d6ed5afa23b", size = 1807491 }, - { url = "https://files.pythonhosted.org/packages/01/72/59a70165eabbc93b1111d42df9ca016a4aa109409db04304829377947028/pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:121ceb0e822f79163dd4699e4c54f5ad38b157084d97b34de8b232bcaad70278", size = 1831953 }, - { url = "https://files.pythonhosted.org/packages/7c/0c/24841136476adafd26f94b45bb718a78cb0500bd7b4f8d667b67c29d7b0d/pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4603137322c18eaf2e06a4495f426aa8d8388940f3c457e7548145011bb68e05", size = 1856071 }, - { url = "https://files.pythonhosted.org/packages/53/5e/c32957a09cceb2af10d7642df45d1e3dbd8596061f700eac93b801de53c0/pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a33cd6ad9017bbeaa9ed78a2e0752c5e250eafb9534f308e7a5f7849b0b1bfb4", size = 2038439 }, - { url = "https://files.pythonhosted.org/packages/e4/8f/979ab3eccd118b638cd6d8f980fea8794f45018255a36044dea40fe579d4/pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15cc53a3179ba0fcefe1e3ae50beb2784dede4003ad2dfd24f81bba4b23a454f", size = 2787416 }, - { url = "https://files.pythonhosted.org/packages/02/1d/00f2e4626565b3b6d3690dab4d4fe1a26edd6a20e53749eb21ca892ef2df/pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45d9c5eb9273aa50999ad6adc6be5e0ecea7e09dbd0d31bd0c65a55a2592ca08", size = 2134548 }, - { url = "https://files.pythonhosted.org/packages/9d/46/3112621204128b90898adc2e721a3cd6cf5626504178d6f32c33b5a43b79/pydantic_core-2.27.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8bf7b66ce12a2ac52d16f776b31d16d91033150266eb796967a7e4621707e4f6", size = 1989882 }, - { url = "https://files.pythonhosted.org/packages/49/ec/557dd4ff5287ffffdf16a31d08d723de6762bb1b691879dc4423392309bc/pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:655d7dd86f26cb15ce8a431036f66ce0318648f8853d709b4167786ec2fa4807", size = 1995829 }, - { url = "https://files.pythonhosted.org/packages/6e/b2/610dbeb74d8d43921a7234555e4c091cb050a2bdb8cfea86d07791ce01c5/pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:5556470f1a2157031e676f776c2bc20acd34c1990ca5f7e56f1ebf938b9ab57c", size = 2091257 }, - { url = "https://files.pythonhosted.org/packages/8c/7f/4bf8e9d26a9118521c80b229291fa9558a07cdd9a968ec2d5c1026f14fbc/pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f69ed81ab24d5a3bd93861c8c4436f54afdf8e8cc421562b0c7504cf3be58206", size = 2143894 }, - { url = "https://files.pythonhosted.org/packages/1f/1c/875ac7139c958f4390f23656fe696d1acc8edf45fb81e4831960f12cd6e4/pydantic_core-2.27.1-cp310-none-win32.whl", hash = "sha256:f5a823165e6d04ccea61a9f0576f345f8ce40ed533013580e087bd4d7442b52c", size = 1816081 }, - { url = "https://files.pythonhosted.org/packages/d7/41/55a117acaeda25ceae51030b518032934f251b1dac3704a53781383e3491/pydantic_core-2.27.1-cp310-none-win_amd64.whl", hash = "sha256:57866a76e0b3823e0b56692d1a0bf722bffb324839bb5b7226a7dbd6c9a40b17", size = 1981109 }, - { url = "https://files.pythonhosted.org/packages/27/39/46fe47f2ad4746b478ba89c561cafe4428e02b3573df882334bd2964f9cb/pydantic_core-2.27.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac3b20653bdbe160febbea8aa6c079d3df19310d50ac314911ed8cc4eb7f8cb8", size = 1895553 }, - { url = "https://files.pythonhosted.org/packages/1c/00/0804e84a78b7fdb394fff4c4f429815a10e5e0993e6ae0e0b27dd20379ee/pydantic_core-2.27.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a5a8e19d7c707c4cadb8c18f5f60c843052ae83c20fa7d44f41594c644a1d330", size = 1807220 }, - { url = "https://files.pythonhosted.org/packages/01/de/df51b3bac9820d38371f5a261020f505025df732ce566c2a2e7970b84c8c/pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f7059ca8d64fea7f238994c97d91f75965216bcbe5f695bb44f354893f11d52", size = 1829727 }, - { url = "https://files.pythonhosted.org/packages/5f/d9/c01d19da8f9e9fbdb2bf99f8358d145a312590374d0dc9dd8dbe484a9cde/pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bed0f8a0eeea9fb72937ba118f9db0cb7e90773462af7962d382445f3005e5a4", size = 1854282 }, - { url = "https://files.pythonhosted.org/packages/5f/84/7db66eb12a0dc88c006abd6f3cbbf4232d26adfd827a28638c540d8f871d/pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3cb37038123447cf0f3ea4c74751f6a9d7afef0eb71aa07bf5f652b5e6a132c", size = 2037437 }, - { url = "https://files.pythonhosted.org/packages/34/ac/a2537958db8299fbabed81167d58cc1506049dba4163433524e06a7d9f4c/pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84286494f6c5d05243456e04223d5a9417d7f443c3b76065e75001beb26f88de", size = 2780899 }, - { url = "https://files.pythonhosted.org/packages/4a/c1/3e38cd777ef832c4fdce11d204592e135ddeedb6c6f525478a53d1c7d3e5/pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acc07b2cfc5b835444b44a9956846b578d27beeacd4b52e45489e93276241025", size = 2135022 }, - { url = "https://files.pythonhosted.org/packages/7a/69/b9952829f80fd555fe04340539d90e000a146f2a003d3fcd1e7077c06c71/pydantic_core-2.27.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4fefee876e07a6e9aad7a8c8c9f85b0cdbe7df52b8a9552307b09050f7512c7e", size = 1987969 }, - { url = "https://files.pythonhosted.org/packages/05/72/257b5824d7988af43460c4e22b63932ed651fe98804cc2793068de7ec554/pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:258c57abf1188926c774a4c94dd29237e77eda19462e5bb901d88adcab6af919", size = 1994625 }, - { url = "https://files.pythonhosted.org/packages/73/c3/78ed6b7f3278a36589bcdd01243189ade7fc9b26852844938b4d7693895b/pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:35c14ac45fcfdf7167ca76cc80b2001205a8d5d16d80524e13508371fb8cdd9c", size = 2090089 }, - { url = "https://files.pythonhosted.org/packages/8d/c8/b4139b2f78579960353c4cd987e035108c93a78371bb19ba0dc1ac3b3220/pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d1b26e1dff225c31897696cab7d4f0a315d4c0d9e8666dbffdb28216f3b17fdc", size = 2142496 }, - { url = "https://files.pythonhosted.org/packages/3e/f8/171a03e97eb36c0b51981efe0f78460554a1d8311773d3d30e20c005164e/pydantic_core-2.27.1-cp311-none-win32.whl", hash = "sha256:2cdf7d86886bc6982354862204ae3b2f7f96f21a3eb0ba5ca0ac42c7b38598b9", size = 1811758 }, - { url = "https://files.pythonhosted.org/packages/6a/fe/4e0e63c418c1c76e33974a05266e5633e879d4061f9533b1706a86f77d5b/pydantic_core-2.27.1-cp311-none-win_amd64.whl", hash = "sha256:3af385b0cee8df3746c3f406f38bcbfdc9041b5c2d5ce3e5fc6637256e60bbc5", size = 1980864 }, - { url = "https://files.pythonhosted.org/packages/50/fc/93f7238a514c155a8ec02fc7ac6376177d449848115e4519b853820436c5/pydantic_core-2.27.1-cp311-none-win_arm64.whl", hash = "sha256:81f2ec23ddc1b476ff96563f2e8d723830b06dceae348ce02914a37cb4e74b89", size = 1864327 }, - { url = "https://files.pythonhosted.org/packages/be/51/2e9b3788feb2aebff2aa9dfbf060ec739b38c05c46847601134cc1fed2ea/pydantic_core-2.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9cbd94fc661d2bab2bc702cddd2d3370bbdcc4cd0f8f57488a81bcce90c7a54f", size = 1895239 }, - { url = "https://files.pythonhosted.org/packages/7b/9e/f8063952e4a7d0127f5d1181addef9377505dcce3be224263b25c4f0bfd9/pydantic_core-2.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f8c4718cd44ec1580e180cb739713ecda2bdee1341084c1467802a417fe0f02", size = 1805070 }, - { url = "https://files.pythonhosted.org/packages/2c/9d/e1d6c4561d262b52e41b17a7ef8301e2ba80b61e32e94520271029feb5d8/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15aae984e46de8d376df515f00450d1522077254ef6b7ce189b38ecee7c9677c", size = 1828096 }, - { url = "https://files.pythonhosted.org/packages/be/65/80ff46de4266560baa4332ae3181fffc4488ea7d37282da1a62d10ab89a4/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ba5e3963344ff25fc8c40da90f44b0afca8cfd89d12964feb79ac1411a260ac", size = 1857708 }, - { url = "https://files.pythonhosted.org/packages/d5/ca/3370074ad758b04d9562b12ecdb088597f4d9d13893a48a583fb47682cdf/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:992cea5f4f3b29d6b4f7f1726ed8ee46c8331c6b4eed6db5b40134c6fe1768bb", size = 2037751 }, - { url = "https://files.pythonhosted.org/packages/b1/e2/4ab72d93367194317b99d051947c071aef6e3eb95f7553eaa4208ecf9ba4/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0325336f348dbee6550d129b1627cb8f5351a9dc91aad141ffb96d4937bd9529", size = 2733863 }, - { url = "https://files.pythonhosted.org/packages/8a/c6/8ae0831bf77f356bb73127ce5a95fe115b10f820ea480abbd72d3cc7ccf3/pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7597c07fbd11515f654d6ece3d0e4e5093edc30a436c63142d9a4b8e22f19c35", size = 2161161 }, - { url = "https://files.pythonhosted.org/packages/f1/f4/b2fe73241da2429400fc27ddeaa43e35562f96cf5b67499b2de52b528cad/pydantic_core-2.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3bbd5d8cc692616d5ef6fbbbd50dbec142c7e6ad9beb66b78a96e9c16729b089", size = 1993294 }, - { url = "https://files.pythonhosted.org/packages/77/29/4bb008823a7f4cc05828198153f9753b3bd4c104d93b8e0b1bfe4e187540/pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:dc61505e73298a84a2f317255fcc72b710b72980f3a1f670447a21efc88f8381", size = 2001468 }, - { url = "https://files.pythonhosted.org/packages/f2/a9/0eaceeba41b9fad851a4107e0cf999a34ae8f0d0d1f829e2574f3d8897b0/pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:e1f735dc43da318cad19b4173dd1ffce1d84aafd6c9b782b3abc04a0d5a6f5bb", size = 2091413 }, - { url = "https://files.pythonhosted.org/packages/d8/36/eb8697729725bc610fd73940f0d860d791dc2ad557faaefcbb3edbd2b349/pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f4e5658dbffe8843a0f12366a4c2d1c316dbe09bb4dfbdc9d2d9cd6031de8aae", size = 2154735 }, - { url = "https://files.pythonhosted.org/packages/52/e5/4f0fbd5c5995cc70d3afed1b5c754055bb67908f55b5cb8000f7112749bf/pydantic_core-2.27.1-cp312-none-win32.whl", hash = "sha256:672ebbe820bb37988c4d136eca2652ee114992d5d41c7e4858cdd90ea94ffe5c", size = 1833633 }, - { url = "https://files.pythonhosted.org/packages/ee/f2/c61486eee27cae5ac781305658779b4a6b45f9cc9d02c90cb21b940e82cc/pydantic_core-2.27.1-cp312-none-win_amd64.whl", hash = "sha256:66ff044fd0bb1768688aecbe28b6190f6e799349221fb0de0e6f4048eca14c16", size = 1986973 }, - { url = "https://files.pythonhosted.org/packages/df/a6/e3f12ff25f250b02f7c51be89a294689d175ac76e1096c32bf278f29ca1e/pydantic_core-2.27.1-cp312-none-win_arm64.whl", hash = "sha256:9a3b0793b1bbfd4146304e23d90045f2a9b5fd5823aa682665fbdaf2a6c28f3e", size = 1883215 }, - { url = "https://files.pythonhosted.org/packages/7c/60/e5eb2d462595ba1f622edbe7b1d19531e510c05c405f0b87c80c1e89d5b1/pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3fa80ac2bd5856580e242dbc202db873c60a01b20309c8319b5c5986fbe53ce6", size = 1894016 }, - { url = "https://files.pythonhosted.org/packages/61/20/da7059855225038c1c4326a840908cc7ca72c7198cb6addb8b92ec81c1d6/pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d950caa237bb1954f1b8c9227b5065ba6875ac9771bb8ec790d956a699b78676", size = 1771648 }, - { url = "https://files.pythonhosted.org/packages/8f/fc/5485cf0b0bb38da31d1d292160a4d123b5977841ddc1122c671a30b76cfd/pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e4216e64d203e39c62df627aa882f02a2438d18a5f21d7f721621f7a5d3611d", size = 1826929 }, - { url = "https://files.pythonhosted.org/packages/a1/ff/fb1284a210e13a5f34c639efc54d51da136074ffbe25ec0c279cf9fbb1c4/pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02a3d637bd387c41d46b002f0e49c52642281edacd2740e5a42f7017feea3f2c", size = 1980591 }, - { url = "https://files.pythonhosted.org/packages/f1/14/77c1887a182d05af74f6aeac7b740da3a74155d3093ccc7ee10b900cc6b5/pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:161c27ccce13b6b0c8689418da3885d3220ed2eae2ea5e9b2f7f3d48f1d52c27", size = 1981326 }, - { url = "https://files.pythonhosted.org/packages/06/aa/6f1b2747f811a9c66b5ef39d7f02fbb200479784c75e98290d70004b1253/pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:19910754e4cc9c63bc1c7f6d73aa1cfee82f42007e407c0f413695c2f7ed777f", size = 1989205 }, - { url = "https://files.pythonhosted.org/packages/7a/d2/8ce2b074d6835f3c88d85f6d8a399790043e9fdb3d0e43455e72d19df8cc/pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:e173486019cc283dc9778315fa29a363579372fe67045e971e89b6365cc035ed", size = 2079616 }, - { url = "https://files.pythonhosted.org/packages/65/71/af01033d4e58484c3db1e5d13e751ba5e3d6b87cc3368533df4c50932c8b/pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:af52d26579b308921b73b956153066481f064875140ccd1dfd4e77db89dbb12f", size = 2133265 }, - { url = "https://files.pythonhosted.org/packages/33/72/f881b5e18fbb67cf2fb4ab253660de3c6899dbb2dba409d0b757e3559e3d/pydantic_core-2.27.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:981fb88516bd1ae8b0cbbd2034678a39dedc98752f264ac9bc5839d3923fa04c", size = 2001864 }, +sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195, upload-time = "2025-04-23T18:33:52.104Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/8d/71db63483d518cbbf290261a1fc2839d17ff89fce7089e08cad07ccfce67/pydantic_core-2.33.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4c5b0a576fb381edd6d27f0a85915c6daf2f8138dc5c267a57c08a62900758c7", size = 2028584, upload-time = "2025-04-23T18:31:03.106Z" }, + { url = "https://files.pythonhosted.org/packages/24/2f/3cfa7244ae292dd850989f328722d2aef313f74ffc471184dc509e1e4e5a/pydantic_core-2.33.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e799c050df38a639db758c617ec771fd8fb7a5f8eaaa4b27b101f266b216a246", size = 1855071, upload-time = "2025-04-23T18:31:04.621Z" }, + { url = "https://files.pythonhosted.org/packages/b3/d3/4ae42d33f5e3f50dd467761304be2fa0a9417fbf09735bc2cce003480f2a/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc46a01bf8d62f227d5ecee74178ffc448ff4e5197c756331f71efcc66dc980f", size = 1897823, upload-time = "2025-04-23T18:31:06.377Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f3/aa5976e8352b7695ff808599794b1fba2a9ae2ee954a3426855935799488/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a144d4f717285c6d9234a66778059f33a89096dfb9b39117663fd8413d582dcc", size = 1983792, upload-time = "2025-04-23T18:31:07.93Z" }, + { url = "https://files.pythonhosted.org/packages/d5/7a/cda9b5a23c552037717f2b2a5257e9b2bfe45e687386df9591eff7b46d28/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cf6373c21bc80b2e0dc88444f41ae60b2f070ed02095754eb5a01df12256de", size = 2136338, upload-time = "2025-04-23T18:31:09.283Z" }, + { url = "https://files.pythonhosted.org/packages/2b/9f/b8f9ec8dd1417eb9da784e91e1667d58a2a4a7b7b34cf4af765ef663a7e5/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dc625f4aa79713512d1976fe9f0bc99f706a9dee21dfd1810b4bbbf228d0e8a", size = 2730998, upload-time = "2025-04-23T18:31:11.7Z" }, + { url = "https://files.pythonhosted.org/packages/47/bc/cd720e078576bdb8255d5032c5d63ee5c0bf4b7173dd955185a1d658c456/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b21b5549499972441da4758d662aeea93f1923f953e9cbaff14b8b9565aef", size = 2003200, upload-time = "2025-04-23T18:31:13.536Z" }, + { url = "https://files.pythonhosted.org/packages/ca/22/3602b895ee2cd29d11a2b349372446ae9727c32e78a94b3d588a40fdf187/pydantic_core-2.33.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bdc25f3681f7b78572699569514036afe3c243bc3059d3942624e936ec93450e", size = 2113890, upload-time = "2025-04-23T18:31:15.011Z" }, + { url = "https://files.pythonhosted.org/packages/ff/e6/e3c5908c03cf00d629eb38393a98fccc38ee0ce8ecce32f69fc7d7b558a7/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fe5b32187cbc0c862ee201ad66c30cf218e5ed468ec8dc1cf49dec66e160cc4d", size = 2073359, upload-time = "2025-04-23T18:31:16.393Z" }, + { url = "https://files.pythonhosted.org/packages/12/e7/6a36a07c59ebefc8777d1ffdaf5ae71b06b21952582e4b07eba88a421c79/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:bc7aee6f634a6f4a95676fcb5d6559a2c2a390330098dba5e5a5f28a2e4ada30", size = 2245883, upload-time = "2025-04-23T18:31:17.892Z" }, + { url = "https://files.pythonhosted.org/packages/16/3f/59b3187aaa6cc0c1e6616e8045b284de2b6a87b027cce2ffcea073adf1d2/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:235f45e5dbcccf6bd99f9f472858849f73d11120d76ea8707115415f8e5ebebf", size = 2241074, upload-time = "2025-04-23T18:31:19.205Z" }, + { url = "https://files.pythonhosted.org/packages/e0/ed/55532bb88f674d5d8f67ab121a2a13c385df382de2a1677f30ad385f7438/pydantic_core-2.33.2-cp311-cp311-win32.whl", hash = "sha256:6368900c2d3ef09b69cb0b913f9f8263b03786e5b2a387706c5afb66800efd51", size = 1910538, upload-time = "2025-04-23T18:31:20.541Z" }, + { url = "https://files.pythonhosted.org/packages/fe/1b/25b7cccd4519c0b23c2dd636ad39d381abf113085ce4f7bec2b0dc755eb1/pydantic_core-2.33.2-cp311-cp311-win_amd64.whl", hash = "sha256:1e063337ef9e9820c77acc768546325ebe04ee38b08703244c1309cccc4f1bab", size = 1952909, upload-time = "2025-04-23T18:31:22.371Z" }, + { url = "https://files.pythonhosted.org/packages/49/a9/d809358e49126438055884c4366a1f6227f0f84f635a9014e2deb9b9de54/pydantic_core-2.33.2-cp311-cp311-win_arm64.whl", hash = "sha256:6b99022f1d19bc32a4c2a0d544fc9a76e3be90f0b3f4af413f87d38749300e65", size = 1897786, upload-time = "2025-04-23T18:31:24.161Z" }, + { url = "https://files.pythonhosted.org/packages/18/8a/2b41c97f554ec8c71f2a8a5f85cb56a8b0956addfe8b0efb5b3d77e8bdc3/pydantic_core-2.33.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a7ec89dc587667f22b6a0b6579c249fca9026ce7c333fc142ba42411fa243cdc", size = 2009000, upload-time = "2025-04-23T18:31:25.863Z" }, + { url = "https://files.pythonhosted.org/packages/a1/02/6224312aacb3c8ecbaa959897af57181fb6cf3a3d7917fd44d0f2917e6f2/pydantic_core-2.33.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3c6db6e52c6d70aa0d00d45cdb9b40f0433b96380071ea80b09277dba021ddf7", size = 1847996, upload-time = "2025-04-23T18:31:27.341Z" }, + { url = "https://files.pythonhosted.org/packages/d6/46/6dcdf084a523dbe0a0be59d054734b86a981726f221f4562aed313dbcb49/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e61206137cbc65e6d5256e1166f88331d3b6238e082d9f74613b9b765fb9025", size = 1880957, upload-time = "2025-04-23T18:31:28.956Z" }, + { url = "https://files.pythonhosted.org/packages/ec/6b/1ec2c03837ac00886ba8160ce041ce4e325b41d06a034adbef11339ae422/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb8c529b2819c37140eb51b914153063d27ed88e3bdc31b71198a198e921e011", size = 1964199, upload-time = "2025-04-23T18:31:31.025Z" }, + { url = "https://files.pythonhosted.org/packages/2d/1d/6bf34d6adb9debd9136bd197ca72642203ce9aaaa85cfcbfcf20f9696e83/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c52b02ad8b4e2cf14ca7b3d918f3eb0ee91e63b3167c32591e57c4317e134f8f", size = 2120296, upload-time = "2025-04-23T18:31:32.514Z" }, + { url = "https://files.pythonhosted.org/packages/e0/94/2bd0aaf5a591e974b32a9f7123f16637776c304471a0ab33cf263cf5591a/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96081f1605125ba0855dfda83f6f3df5ec90c61195421ba72223de35ccfb2f88", size = 2676109, upload-time = "2025-04-23T18:31:33.958Z" }, + { url = "https://files.pythonhosted.org/packages/f9/41/4b043778cf9c4285d59742281a769eac371b9e47e35f98ad321349cc5d61/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1", size = 2002028, upload-time = "2025-04-23T18:31:39.095Z" }, + { url = "https://files.pythonhosted.org/packages/cb/d5/7bb781bf2748ce3d03af04d5c969fa1308880e1dca35a9bd94e1a96a922e/pydantic_core-2.33.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:572c7e6c8bb4774d2ac88929e3d1f12bc45714ae5ee6d9a788a9fb35e60bb04b", size = 2100044, upload-time = "2025-04-23T18:31:41.034Z" }, + { url = "https://files.pythonhosted.org/packages/fe/36/def5e53e1eb0ad896785702a5bbfd25eed546cdcf4087ad285021a90ed53/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:db4b41f9bd95fbe5acd76d89920336ba96f03e149097365afe1cb092fceb89a1", size = 2058881, upload-time = "2025-04-23T18:31:42.757Z" }, + { url = "https://files.pythonhosted.org/packages/01/6c/57f8d70b2ee57fc3dc8b9610315949837fa8c11d86927b9bb044f8705419/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:fa854f5cf7e33842a892e5c73f45327760bc7bc516339fda888c75ae60edaeb6", size = 2227034, upload-time = "2025-04-23T18:31:44.304Z" }, + { url = "https://files.pythonhosted.org/packages/27/b9/9c17f0396a82b3d5cbea4c24d742083422639e7bb1d5bf600e12cb176a13/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5f483cfb75ff703095c59e365360cb73e00185e01aaea067cd19acffd2ab20ea", size = 2234187, upload-time = "2025-04-23T18:31:45.891Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6a/adf5734ffd52bf86d865093ad70b2ce543415e0e356f6cacabbc0d9ad910/pydantic_core-2.33.2-cp312-cp312-win32.whl", hash = "sha256:9cb1da0f5a471435a7bc7e439b8a728e8b61e59784b2af70d7c169f8dd8ae290", size = 1892628, upload-time = "2025-04-23T18:31:47.819Z" }, + { url = "https://files.pythonhosted.org/packages/43/e4/5479fecb3606c1368d496a825d8411e126133c41224c1e7238be58b87d7e/pydantic_core-2.33.2-cp312-cp312-win_amd64.whl", hash = "sha256:f941635f2a3d96b2973e867144fde513665c87f13fe0e193c158ac51bfaaa7b2", size = 1955866, upload-time = "2025-04-23T18:31:49.635Z" }, + { url = "https://files.pythonhosted.org/packages/0d/24/8b11e8b3e2be9dd82df4b11408a67c61bb4dc4f8e11b5b0fc888b38118b5/pydantic_core-2.33.2-cp312-cp312-win_arm64.whl", hash = "sha256:cca3868ddfaccfbc4bfb1d608e2ccaaebe0ae628e1416aeb9c4d88c001bb45ab", size = 1888894, upload-time = "2025-04-23T18:31:51.609Z" }, + { url = "https://files.pythonhosted.org/packages/46/8c/99040727b41f56616573a28771b1bfa08a3d3fe74d3d513f01251f79f172/pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f", size = 2015688, upload-time = "2025-04-23T18:31:53.175Z" }, + { url = "https://files.pythonhosted.org/packages/3a/cc/5999d1eb705a6cefc31f0b4a90e9f7fc400539b1a1030529700cc1b51838/pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6", size = 1844808, upload-time = "2025-04-23T18:31:54.79Z" }, + { url = "https://files.pythonhosted.org/packages/6f/5e/a0a7b8885c98889a18b6e376f344da1ef323d270b44edf8174d6bce4d622/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef", size = 1885580, upload-time = "2025-04-23T18:31:57.393Z" }, + { url = "https://files.pythonhosted.org/packages/3b/2a/953581f343c7d11a304581156618c3f592435523dd9d79865903272c256a/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a", size = 1973859, upload-time = "2025-04-23T18:31:59.065Z" }, + { url = "https://files.pythonhosted.org/packages/e6/55/f1a813904771c03a3f97f676c62cca0c0a4138654107c1b61f19c644868b/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916", size = 2120810, upload-time = "2025-04-23T18:32:00.78Z" }, + { url = "https://files.pythonhosted.org/packages/aa/c3/053389835a996e18853ba107a63caae0b9deb4a276c6b472931ea9ae6e48/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a", size = 2676498, upload-time = "2025-04-23T18:32:02.418Z" }, + { url = "https://files.pythonhosted.org/packages/eb/3c/f4abd740877a35abade05e437245b192f9d0ffb48bbbbd708df33d3cda37/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d", size = 2000611, upload-time = "2025-04-23T18:32:04.152Z" }, + { url = "https://files.pythonhosted.org/packages/59/a7/63ef2fed1837d1121a894d0ce88439fe3e3b3e48c7543b2a4479eb99c2bd/pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56", size = 2107924, upload-time = "2025-04-23T18:32:06.129Z" }, + { url = "https://files.pythonhosted.org/packages/04/8f/2551964ef045669801675f1cfc3b0d74147f4901c3ffa42be2ddb1f0efc4/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5", size = 2063196, upload-time = "2025-04-23T18:32:08.178Z" }, + { url = "https://files.pythonhosted.org/packages/26/bd/d9602777e77fc6dbb0c7db9ad356e9a985825547dce5ad1d30ee04903918/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e", size = 2236389, upload-time = "2025-04-23T18:32:10.242Z" }, + { url = "https://files.pythonhosted.org/packages/42/db/0e950daa7e2230423ab342ae918a794964b053bec24ba8af013fc7c94846/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162", size = 2239223, upload-time = "2025-04-23T18:32:12.382Z" }, + { url = "https://files.pythonhosted.org/packages/58/4d/4f937099c545a8a17eb52cb67fe0447fd9a373b348ccfa9a87f141eeb00f/pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849", size = 1900473, upload-time = "2025-04-23T18:32:14.034Z" }, + { url = "https://files.pythonhosted.org/packages/a0/75/4a0a9bac998d78d889def5e4ef2b065acba8cae8c93696906c3a91f310ca/pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9", size = 1955269, upload-time = "2025-04-23T18:32:15.783Z" }, + { url = "https://files.pythonhosted.org/packages/f9/86/1beda0576969592f1497b4ce8e7bc8cbdf614c352426271b1b10d5f0aa64/pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9", size = 1893921, upload-time = "2025-04-23T18:32:18.473Z" }, + { url = "https://files.pythonhosted.org/packages/a4/7d/e09391c2eebeab681df2b74bfe6c43422fffede8dc74187b2b0bf6fd7571/pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac", size = 1806162, upload-time = "2025-04-23T18:32:20.188Z" }, + { url = "https://files.pythonhosted.org/packages/f1/3d/847b6b1fed9f8ed3bb95a9ad04fbd0b212e832d4f0f50ff4d9ee5a9f15cf/pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5", size = 1981560, upload-time = "2025-04-23T18:32:22.354Z" }, + { url = "https://files.pythonhosted.org/packages/6f/9a/e73262f6c6656262b5fdd723ad90f518f579b7bc8622e43a942eec53c938/pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9", size = 1935777, upload-time = "2025-04-23T18:32:25.088Z" }, + { url = "https://files.pythonhosted.org/packages/7b/27/d4ae6487d73948d6f20dddcd94be4ea43e74349b56eba82e9bdee2d7494c/pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:dd14041875d09cc0f9308e37a6f8b65f5585cf2598a53aa0123df8b129d481f8", size = 2025200, upload-time = "2025-04-23T18:33:14.199Z" }, + { url = "https://files.pythonhosted.org/packages/f1/b8/b3cb95375f05d33801024079b9392a5ab45267a63400bf1866e7ce0f0de4/pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d87c561733f66531dced0da6e864f44ebf89a8fba55f31407b00c2f7f9449593", size = 1859123, upload-time = "2025-04-23T18:33:16.555Z" }, + { url = "https://files.pythonhosted.org/packages/05/bc/0d0b5adeda59a261cd30a1235a445bf55c7e46ae44aea28f7bd6ed46e091/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f82865531efd18d6e07a04a17331af02cb7a651583c418df8266f17a63c6612", size = 1892852, upload-time = "2025-04-23T18:33:18.513Z" }, + { url = "https://files.pythonhosted.org/packages/3e/11/d37bdebbda2e449cb3f519f6ce950927b56d62f0b84fd9cb9e372a26a3d5/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bfb5112df54209d820d7bf9317c7a6c9025ea52e49f46b6a2060104bba37de7", size = 2067484, upload-time = "2025-04-23T18:33:20.475Z" }, + { url = "https://files.pythonhosted.org/packages/8c/55/1f95f0a05ce72ecb02a8a8a1c3be0579bbc29b1d5ab68f1378b7bebc5057/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:64632ff9d614e5eecfb495796ad51b0ed98c453e447a76bcbeeb69615079fc7e", size = 2108896, upload-time = "2025-04-23T18:33:22.501Z" }, + { url = "https://files.pythonhosted.org/packages/53/89/2b2de6c81fa131f423246a9109d7b2a375e83968ad0800d6e57d0574629b/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f889f7a40498cc077332c7ab6b4608d296d852182211787d4f3ee377aaae66e8", size = 2069475, upload-time = "2025-04-23T18:33:24.528Z" }, + { url = "https://files.pythonhosted.org/packages/b8/e9/1f7efbe20d0b2b10f6718944b5d8ece9152390904f29a78e68d4e7961159/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:de4b83bb311557e439b9e186f733f6c645b9417c84e2eb8203f3f820a4b988bf", size = 2239013, upload-time = "2025-04-23T18:33:26.621Z" }, + { url = "https://files.pythonhosted.org/packages/3c/b2/5309c905a93811524a49b4e031e9851a6b00ff0fb668794472ea7746b448/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f68293f055f51b51ea42fafc74b6aad03e70e191799430b90c13d643059ebb", size = 2238715, upload-time = "2025-04-23T18:33:28.656Z" }, + { url = "https://files.pythonhosted.org/packages/32/56/8a7ca5d2cd2cda1d245d34b1c9a942920a718082ae8e54e5f3e5a58b7add/pydantic_core-2.33.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:329467cecfb529c925cf2bbd4d60d2c509bc2fb52a20c1045bf09bb70971a9c1", size = 2066757, upload-time = "2025-04-23T18:33:30.645Z" }, ] [[package]] name = "pygments" -version = "2.18.0" +version = "2.19.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8e/62/8336eff65bcbc8e4cb5d05b55faf041285951b6e80f33e2bff2024788f31/pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", size = 4891905 } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f7/3f/01c8b82017c199075f8f788d0d906b9ffbbc5a47dc9918a945e13d5a2bda/pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a", size = 1205513 }, + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, ] [[package]] @@ -2019,60 +2488,60 @@ dependencies = [ { name = "scikit-learn" }, { name = "scipy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7e/58/560a4db5eb3794d922fe55804b10326534ded3d971e1933c1eef91193f5e/pynndescent-0.5.13.tar.gz", hash = "sha256:d74254c0ee0a1eeec84597d5fe89fedcf778593eeabe32c2f97412934a9800fb", size = 2975955 } +sdist = { url = "https://files.pythonhosted.org/packages/7e/58/560a4db5eb3794d922fe55804b10326534ded3d971e1933c1eef91193f5e/pynndescent-0.5.13.tar.gz", hash = "sha256:d74254c0ee0a1eeec84597d5fe89fedcf778593eeabe32c2f97412934a9800fb", size = 2975955, upload-time = "2024-06-17T15:48:32.914Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/53/d23a97e0a2c690d40b165d1062e2c4ccc796be458a1ce59f6ba030434663/pynndescent-0.5.13-py3-none-any.whl", hash = "sha256:69aabb8f394bc631b6ac475a1c7f3994c54adf3f51cd63b2730fefba5771b949", size = 56850 }, + { url = "https://files.pythonhosted.org/packages/d2/53/d23a97e0a2c690d40b165d1062e2c4ccc796be458a1ce59f6ba030434663/pynndescent-0.5.13-py3-none-any.whl", hash = "sha256:69aabb8f394bc631b6ac475a1c7f3994c54adf3f51cd63b2730fefba5771b949", size = 56850, upload-time = "2024-06-17T15:48:31.184Z" }, ] [[package]] name = "pyparsing" -version = "3.2.0" +version = "3.2.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8c/d5/e5aeee5387091148a19e1145f63606619cb5f20b83fccb63efae6474e7b2/pyparsing-3.2.0.tar.gz", hash = "sha256:cbf74e27246d595d9a74b186b810f6fbb86726dbf3b9532efb343f6d7294fe9c", size = 920984 } +sdist = { url = "https://files.pythonhosted.org/packages/bb/22/f1129e69d94ffff626bdb5c835506b3a5b4f3d070f17ea295e12c2c6f60f/pyparsing-3.2.3.tar.gz", hash = "sha256:b9c13f1ab8b3b542f72e28f634bad4de758ab3ce4546e4301970ad6fa77c38be", size = 1088608, upload-time = "2025-03-25T05:01:28.114Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/be/ec/2eb3cd785efd67806c46c13a17339708ddc346cbb684eade7a6e6f79536a/pyparsing-3.2.0-py3-none-any.whl", hash = "sha256:93d9577b88da0bbea8cc8334ee8b918ed014968fd2ec383e868fb8afb1ccef84", size = 106921 }, + { url = "https://files.pythonhosted.org/packages/05/e7/df2285f3d08fee213f2d041540fa4fc9ca6c2d44cf36d3a035bf2a8d2bcc/pyparsing-3.2.3-py3-none-any.whl", hash = "sha256:a749938e02d6fd0b59b356ca504a24982314bb090c383e3cf201c95ef7e2bfcf", size = 111120, upload-time = "2025-03-25T05:01:24.908Z" }, ] [[package]] name = "pytest" -version = "8.3.3" +version = "8.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, - { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8b/6c/62bbd536103af674e227c41a8f3dcd022d591f6eed5facb5a0f31ee33bbc/pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181", size = 1442487 } +sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714, upload-time = "2025-06-18T05:48:06.109Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6b/77/7440a06a8ead44c7757a64362dd22df5760f9b12dc5f11b6188cd2fc27a0/pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2", size = 342341 }, + { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474, upload-time = "2025-06-18T05:48:03.955Z" }, ] [[package]] name = "pytest-asyncio" -version = "0.24.0" +version = "1.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/52/6d/c6cf50ce320cf8611df7a1254d86233b3df7cc07f9b5f5cbcb82e08aa534/pytest_asyncio-0.24.0.tar.gz", hash = "sha256:d081d828e576d85f875399194281e92bf8a68d60d72d1a2faf2feddb6c46b276", size = 49855 } +sdist = { url = "https://files.pythonhosted.org/packages/4e/51/f8794af39eeb870e87a8c8068642fc07bce0c854d6865d7dd0f2a9d338c2/pytest_asyncio-1.1.0.tar.gz", hash = "sha256:796aa822981e01b68c12e4827b8697108f7205020f24b5793b3c41555dab68ea", size = 46652, upload-time = "2025-07-16T04:29:26.393Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/96/31/6607dab48616902f76885dfcf62c08d929796fc3b2d2318faf9fd54dbed9/pytest_asyncio-0.24.0-py3-none-any.whl", hash = "sha256:a811296ed596b69bf0b6f3dc40f83bcaf341b155a269052d82efa2b25ac7037b", size = 18024 }, + { url = "https://files.pythonhosted.org/packages/c7/9d/bf86eddabf8c6c9cb1ea9a869d6873b46f105a5d292d3a6f7071f5b07935/pytest_asyncio-1.1.0-py3-none-any.whl", hash = "sha256:5fe2d69607b0bd75c656d1211f969cadba035030156745ee09e7d71740e58ecf", size = 15157, upload-time = "2025-07-16T04:29:24.929Z" }, ] [[package]] name = "pytest-cov" -version = "6.0.0" +version = "6.2.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "coverage", extra = ["toml"] }, + { name = "pluggy" }, { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/be/45/9b538de8cef30e17c7b45ef42f538a94889ed6a16f2387a6c89e73220651/pytest-cov-6.0.0.tar.gz", hash = "sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0", size = 66945 } +sdist = { url = "https://files.pythonhosted.org/packages/18/99/668cade231f434aaa59bbfbf49469068d2ddd945000621d3d165d2e7dd7b/pytest_cov-6.2.1.tar.gz", hash = "sha256:25cc6cc0a5358204b8108ecedc51a9b57b34cc6b8c967cc2c01a4e00d8a67da2", size = 69432, upload-time = "2025-06-12T10:47:47.684Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/36/3b/48e79f2cd6a61dbbd4807b4ed46cb564b4fd50a76166b1c4ea5c1d9e2371/pytest_cov-6.0.0-py3-none-any.whl", hash = "sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35", size = 22949 }, + { url = "https://files.pythonhosted.org/packages/bc/16/4ea354101abb1287856baa4af2732be351c7bee728065aed451b678153fd/pytest_cov-6.2.1-py3-none-any.whl", hash = "sha256:f5bc4c23f42f1cdd23c70b1dab1bbaef4fc505ba950d53e0081d0730dd7e86d5", size = 24644, upload-time = "2025-06-12T10:47:45.932Z" }, ] [[package]] @@ -2082,207 +2551,192 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "six" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 } +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 }, + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, ] [[package]] name = "python-json-logger" -version = "2.0.7" +version = "3.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4f/da/95963cebfc578dabd323d7263958dfb68898617912bb09327dd30e9c8d13/python-json-logger-2.0.7.tar.gz", hash = "sha256:23e7ec02d34237c5aa1e29a070193a4ea87583bb4e7f8fd06d3de8264c4b2e1c", size = 10508 } +sdist = { url = "https://files.pythonhosted.org/packages/9e/de/d3144a0bceede957f961e975f3752760fbe390d57fbe194baf709d8f1f7b/python_json_logger-3.3.0.tar.gz", hash = "sha256:12b7e74b17775e7d565129296105bbe3910842d9d0eb083fc83a6a617aa8df84", size = 16642, upload-time = "2025-03-07T07:08:27.301Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/35/a6/145655273568ee78a581e734cf35beb9e33a370b29c5d3c8fee3744de29f/python_json_logger-2.0.7-py3-none-any.whl", hash = "sha256:f380b826a991ebbe3de4d897aeec42760035ac760345e57b812938dc8b35e2bd", size = 8067 }, + { url = "https://files.pythonhosted.org/packages/08/20/0f2523b9e50a8052bc6a8b732dfc8568abbdc42010aef03a2d750bdab3b2/python_json_logger-3.3.0-py3-none-any.whl", hash = "sha256:dd980fae8cffb24c13caf6e158d3d61c0d6d22342f932cb6e9deedab3d35eec7", size = 15163, upload-time = "2025-03-07T07:08:25.627Z" }, ] [[package]] name = "python-libsbml" -version = "5.20.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5d/74/1bf1b9883de7bc928e1727e4502c690ec09a8f7b9f2d53edb8fa452d23c3/python_libsbml-5.20.4.tar.gz", hash = "sha256:b055f98fe65be258ae266fde343157cbf41e3ed3fc19b3698f2a66afc74cdaf8", size = 48669079 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/16/ca/572dd53742081b13f59f57a4f114d6fd32ee177cf7cff45eadc38b26e70e/python_libsbml-5.20.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2c7a271cdaef200fe66f92ceefb85bb0dc647fa4fe966cec84af7efb685e93fd", size = 6320391 }, - { url = "https://files.pythonhosted.org/packages/1c/16/b92b5d1607b08b29df6636cef1d3d0c4e6ab0a7af8abc858e6564c1750a4/python_libsbml-5.20.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a69d9130148fc7aa85b4c42f804c6111c167711d39ed3a64145d15cb0296ec57", size = 6075826 }, - { url = "https://files.pythonhosted.org/packages/34/14/60557f93f37dbdd0a58796e0fd832b6cc3e8194caaadc7a4e78d83ef15e6/python_libsbml-5.20.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0a9f71d4a6ff17d4ec282f64f15279b30b9e0ec2becba5c3fb8d466df8eeb77", size = 7442963 }, - { url = "https://files.pythonhosted.org/packages/27/91/968a70814dceb1a1002c313ac80de94c6515c6ed9d580d569371581ec549/python_libsbml-5.20.4-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dfa145c81690ba5f218702a9526eefd135cb95016142144b986c6e8fab056fe6", size = 7837577 }, - { url = "https://files.pythonhosted.org/packages/10/3f/b7bb4c06c4de558a71117a18d5e59f30f0719e43244c7e0e9010370eff11/python_libsbml-5.20.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e3fc4581ced13a6b817869ae01419efae4bbacaa2fd24483017fe6b4116d8a1", size = 7989795 }, - { url = "https://files.pythonhosted.org/packages/10/33/78752be98d7cb891266d15758057efc3ac392ffa5203a2947506fa15856f/python_libsbml-5.20.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:d8e7f62372cda654bc53c15b7187aa06a41b8b5a0287d6fcfb4e5ab826ab1cc9", size = 8626500 }, - { url = "https://files.pythonhosted.org/packages/c0/20/429e411767983fd38d520470acf8c34d08299d25bf05e6456210796256a3/python_libsbml-5.20.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9cb6ea007c848671ce419ebef870df374e7e2ef4c63392e1f6d4bfe4e2131a63", size = 8603444 }, - { url = "https://files.pythonhosted.org/packages/e9/0f/558289f95919730d7e341337b14d880c89912277550f03a3f78e585706b3/python_libsbml-5.20.4-cp310-cp310-win32.whl", hash = "sha256:a8f76d1992366abd1970a9a12e5df7ae9da1e5f542cca058e370bd170d3fe381", size = 5226739 }, - { url = "https://files.pythonhosted.org/packages/60/5a/f435f7a12f11f1cc8cf505452814f21cde6ef6d8e2f75a4a323ab47bd0da/python_libsbml-5.20.4-cp310-cp310-win_amd64.whl", hash = "sha256:3bc3e2d2a077d4c7d1896e589dfe02fa663954fa1ea5e2f04a412549cc005135", size = 5948566 }, - { url = "https://files.pythonhosted.org/packages/28/5a/9b2d31a91f5e94ff44bca259fb8ea57dab7e2cadd66d54888dedbd7efdb7/python_libsbml-5.20.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fcec0a0d2077c80d946f678900b3cbfa3180d1f958d7f91e79cdaa36d23831c6", size = 6320390 }, - { url = "https://files.pythonhosted.org/packages/19/e4/79a57f56cc0fcb9ccf74a480a2102a5b91109958fbd830f92c2e6435e905/python_libsbml-5.20.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:57afb1de6af349da4db279376f167ae5274018481aeda0192481e1333d64fd98", size = 6075824 }, - { url = "https://files.pythonhosted.org/packages/a6/a7/18dbc2129f0187cb00404de81ff51fd7a907a11dedfed28c10d3b03eac32/python_libsbml-5.20.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c9880a45513b0db4b799dbfb34bfa4ff64b9230ce71ceec7dfdfbe54f13c301", size = 7443770 }, - { url = "https://files.pythonhosted.org/packages/50/91/53c5c6a005eb529fc844ef5cc6f079cd85070d2a2e96227cd3644eceec88/python_libsbml-5.20.4-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d9f36f16fe819193e3b941bb055a09b1e380c147e9a922fd9365f4d2078556ba", size = 7837406 }, - { url = "https://files.pythonhosted.org/packages/ff/4b/f11aab01f1483ca770ef7af61a41005a1fc5a3b1004c097b0a92e7046e61/python_libsbml-5.20.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ecace54a0a46761b3060869c8d949b7c5c805334eeb1d2a668162860c6c3d7b6", size = 7989747 }, - { url = "https://files.pythonhosted.org/packages/90/7f/57e791cf4495ba2e8e07386ee070373eb925cbb7ffb80f4dc2db42e1f7ac/python_libsbml-5.20.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:570319329110a2ed6695963c9f28436ccb16a5d91df8f411d2f06e5e075590e1", size = 8627295 }, - { url = "https://files.pythonhosted.org/packages/8b/13/a97e56c822875a7ea616277e1801e2bea3f536ecbb292297cf947bb11bee/python_libsbml-5.20.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d51edbc94c306dcd70a23de221fafc76b905155d8e6f931ef1014dc9904e51c6", size = 8603150 }, - { url = "https://files.pythonhosted.org/packages/aa/24/53784997e5bae3def9e6279fdc71c70c59e4efeea8a31adce5816778d2e1/python_libsbml-5.20.4-cp311-cp311-win32.whl", hash = "sha256:12902ecbee2fa47b3b7a9525f06a996fa3cfb1859a441fe84008d53fc9d9f4a4", size = 5225793 }, - { url = "https://files.pythonhosted.org/packages/15/bd/6838154413a83a8f6dc5b60bafd80ba73f1554c47c99f39cfe958c64d907/python_libsbml-5.20.4-cp311-cp311-win_amd64.whl", hash = "sha256:f568008f07d58769f974a11b272651af8e01d0dca7050081b23c8c9b07218c64", size = 5948904 }, - { url = "https://files.pythonhosted.org/packages/30/6c/43a8b4e49ac8885d9a9ae856c8a442864d987a40e82b32358ea718a75441/python_libsbml-5.20.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9ad98ad3745c84bee3ee34c24b873be9cf3ba5329da5b481c72db60bf355bec5", size = 6341267 }, - { url = "https://files.pythonhosted.org/packages/de/4d/3bad65cbb54ba14d5d983874d47d2352efe6f45cd737573d64d6091980ba/python_libsbml-5.20.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d0c54eec94a84c270330c2fcff0c48af07d30d9b6fd2d750f9c01b61acf6c514", size = 6074769 }, - { url = "https://files.pythonhosted.org/packages/8c/db/3f9f75d42106144df9cec628a4c9f24a024256372f7155f24f4608932c14/python_libsbml-5.20.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4963363f5f0873bbbc2303a189b462f897ca62fe4a164a142ec6878e8f3c6b41", size = 7441180 }, - { url = "https://files.pythonhosted.org/packages/d2/0a/a0ac99ea56235166b5441bd9c605fbbfa5130f8611a725da6368d628d4a4/python_libsbml-5.20.4-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7db73d38dc3e09855780d5756009b511b601fd8aca04807d7d06dbfc400331b6", size = 7823247 }, - { url = "https://files.pythonhosted.org/packages/d9/d3/9db568a391f82ec47da42ae557f3e429acfee6364b205a06ae2ccb602af1/python_libsbml-5.20.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:269f616a63a5e46b863bb5d75370ccff90d719e42af96a3e7a87825364ad2556", size = 7974685 }, - { url = "https://files.pythonhosted.org/packages/6f/b2/3dae1e7f2d5742f1b9aae565aea55d2a978059c324a891a9bfd921b75024/python_libsbml-5.20.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:fefe7651f8981be20f499020139f07bc14e00c1a04f968eeb26e7d60e359dbbd", size = 8619623 }, - { url = "https://files.pythonhosted.org/packages/f4/48/79f5737c66329717f1c98f7ffad4af5bcf053477ef76f4e65c71b20c573e/python_libsbml-5.20.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b1ef224f746aac4e1b0f917113b6334abd2fa3eb63bde41149a1b006bacfba81", size = 8605996 }, - { url = "https://files.pythonhosted.org/packages/4c/28/b5049445492235606844c1d8e88317bd0545417ce1c268a4c34f98946d3a/python_libsbml-5.20.4-cp312-cp312-win32.whl", hash = "sha256:b5cc68b5fe6d139a4557cba9d9913b3e196582bdb7975bea6a2c25faaecdfadb", size = 5231032 }, - { url = "https://files.pythonhosted.org/packages/e3/ee/4bbb01a4c7ce916fc2f26d836aa5aa0e3a90f9e526f8d6effefdf06079bc/python_libsbml-5.20.4-cp312-cp312-win_amd64.whl", hash = "sha256:40c5e9ec86c467b4f325b5365ca369ecc1c9ced608e390d3cc1726f79da68968", size = 5949245 }, - { url = "https://files.pythonhosted.org/packages/b7/39/85ff81ad6a098f069e6680accd97659d02efc62c32a81416717e65c00f09/python_libsbml-5.20.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f15a361aadb2c49fa7eb952818be1cfe3de30f5767e20ee6f03189743427e64", size = 7445892 }, +version = "5.20.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5d/4b/b49fe7384cc9e727e88c58713edc3b4a1c469673937d8d31cafe23261120/python_libsbml-5.20.5.tar.gz", hash = "sha256:a54b7377b125043fd40df0ec77900c12f99c7f7d48b9e12e82b1aef9502cc09a", size = 41798937, upload-time = "2025-05-05T06:44:52.573Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a1/ef/d44ea1ff0042439c29cc864c353e1ca9a062a753d5e8288ca6e6e4ba853c/python_libsbml-5.20.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a39655e53cdaf5600f80c3bfcb1336838818544a7a2846904869a42806f87f2a", size = 6346489, upload-time = "2025-05-05T06:43:35.813Z" }, + { url = "https://files.pythonhosted.org/packages/31/66/d5fc713d4a369d17522e3816be5234289cd27fc731c112ce698387382d89/python_libsbml-5.20.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:926ff0292b897d065f4b9f7e0bfab79a02f57851dff07a036560efd4c350316a", size = 6094638, upload-time = "2025-05-05T06:43:37.403Z" }, + { url = "https://files.pythonhosted.org/packages/b6/3f/199d494311da757de5a94404e88a0c6bbae99e64865c98dcf415b03d595a/python_libsbml-5.20.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a8fd69b10f45d9e56c76af882788ff1bc4b663fe5f328a419c02bcb2089740fc", size = 7602787, upload-time = "2025-05-05T06:43:38.886Z" }, + { url = "https://files.pythonhosted.org/packages/0f/17/7f1f0ad2f3b0054d1e762b6cbdd25153fd904135ce07561b0fd79dd83d90/python_libsbml-5.20.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:942d90ef2bfa9646cc03738e21c5a6533571eae509211a6a18dabcf067d00e28", size = 8136465, upload-time = "2025-05-05T06:43:40.804Z" }, + { url = "https://files.pythonhosted.org/packages/44/a5/ef3cdd88c805181ed3da79a9ec85ee707872bacb7bc1cbc736efa9c3cd78/python_libsbml-5.20.5-cp311-cp311-win_amd64.whl", hash = "sha256:1716da06efd180903d2a4d0532b8c8c6d751b8756d9047bca63f8c30aad7bd35", size = 6028382, upload-time = "2025-05-05T06:43:42.661Z" }, + { url = "https://files.pythonhosted.org/packages/a6/d6/269bd9d7dfb69025e98c7afe2285a9c6d66b980209bbdbd54ffd995c592f/python_libsbml-5.20.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e3e746ad338b2b4debf433ad3e8dea79984666c72be398f32d1c4a7d1ddb105f", size = 6363556, upload-time = "2025-05-05T06:43:44.062Z" }, + { url = "https://files.pythonhosted.org/packages/ad/c0/3ba180b1d18c5d1427e3772fa1402f72ce6edaac345e4aab14af61f50916/python_libsbml-5.20.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9f534be1c421e706c4473c33b7553a574f51b84e2dd1d4612c9c5a62f7cf9134", size = 6094716, upload-time = "2025-05-05T06:43:45.877Z" }, + { url = "https://files.pythonhosted.org/packages/eb/7f/59669e43e75428a6e740bb11bf40f0a5f4afc7a6604f7071560dd1f7fab3/python_libsbml-5.20.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b86197750f3fe1cde04303ac320fe12fce625553bbfe39eaf1c1f101c0e086dd", size = 7621189, upload-time = "2025-05-05T06:43:47.79Z" }, + { url = "https://files.pythonhosted.org/packages/1f/02/696c5a0dc72a3949224207534219afe54951381f2ad4ee1df5e03833edbe/python_libsbml-5.20.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5abf5873f2aed8e1286be28f2ae6cf1285840760cfc0d6cbd20d0b217860f3ce", size = 8155039, upload-time = "2025-05-05T06:43:49.21Z" }, + { url = "https://files.pythonhosted.org/packages/11/68/528c874841022d90fc93854197d327aab7c65b36c8a8d954a5280e9520b4/python_libsbml-5.20.5-cp312-cp312-win_amd64.whl", hash = "sha256:6a51615a6cd7b6b338ff65e3996a4428e71b73d4de9fbf7ee8425a1d5e16647e", size = 6030343, upload-time = "2025-05-05T06:43:51.299Z" }, + { url = "https://files.pythonhosted.org/packages/9f/8f/e98feeb2d0a6ef95716123cb808b25723dabbcde5d0f555e89360be1d8d6/python_libsbml-5.20.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:45f8f60379fe5c7d9776b278100622b8df988cce9fbf6e91b53231897ae044f8", size = 6363553, upload-time = "2025-05-05T06:43:52.766Z" }, + { url = "https://files.pythonhosted.org/packages/f5/45/2e64419d50428b67a7592850121afee11f83448781506bbc389f737c2597/python_libsbml-5.20.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d25b106640d55f86e155a149fb7e9741a74c33f211ad0a15ba5d848a04909119", size = 6094719, upload-time = "2025-05-05T06:43:54.246Z" }, + { url = "https://files.pythonhosted.org/packages/46/8f/3e211bbdaf69ca0c789530353cdf02711f95e70ac8581a08ce0c45903c80/python_libsbml-5.20.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:198c5cf1cc82c46e9665e048799c0a0d4d699cffff959af6d9e97dd145e967d9", size = 7621140, upload-time = "2025-05-05T06:43:56.159Z" }, + { url = "https://files.pythonhosted.org/packages/c6/92/a8a86812776326ffdfac6c5addc7581f6399f7b825b31dd90e211f63739f/python_libsbml-5.20.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0dedc59f6eb5c901a127751ee314a83bb30bdec2355c99c99205aef6484d6f0", size = 8155062, upload-time = "2025-05-05T06:43:57.669Z" }, + { url = "https://files.pythonhosted.org/packages/b8/49/70f6288db3ce3ef006627318d518235836c47b34e4aa7716760e33b639b9/python_libsbml-5.20.5-cp313-cp313-win_amd64.whl", hash = "sha256:763222865e39d51e408c2c9af3dafa0d58f613e75d9ff117de8f8a2b9f7eb59e", size = 6027822, upload-time = "2025-05-05T06:43:59.128Z" }, ] [[package]] name = "pytz" -version = "2024.2" +version = "2025.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3a/31/3c70bf7603cc2dca0f19bdc53b4537a797747a58875b552c8c413d963a3f/pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a", size = 319692 } +sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884, upload-time = "2025-03-25T02:25:00.538Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/11/c3/005fcca25ce078d2cc29fd559379817424e94885510568bc1bc53d7d5846/pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725", size = 508002 }, + { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload-time = "2025-03-25T02:24:58.468Z" }, ] [[package]] name = "pywin32" -version = "308" +version = "311" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/72/a6/3e9f2c474895c1bb61b11fa9640be00067b5c5b363c501ee9c3fa53aec01/pywin32-308-cp310-cp310-win32.whl", hash = "sha256:796ff4426437896550d2981b9c2ac0ffd75238ad9ea2d3bfa67a1abd546d262e", size = 5927028 }, - { url = "https://files.pythonhosted.org/packages/d9/b4/84e2463422f869b4b718f79eb7530a4c1693e96b8a4e5e968de38be4d2ba/pywin32-308-cp310-cp310-win_amd64.whl", hash = "sha256:4fc888c59b3c0bef905ce7eb7e2106a07712015ea1c8234b703a088d46110e8e", size = 6558484 }, - { url = "https://files.pythonhosted.org/packages/9f/8f/fb84ab789713f7c6feacaa08dad3ec8105b88ade8d1c4f0f0dfcaaa017d6/pywin32-308-cp310-cp310-win_arm64.whl", hash = "sha256:a5ab5381813b40f264fa3495b98af850098f814a25a63589a8e9eb12560f450c", size = 7971454 }, - { url = "https://files.pythonhosted.org/packages/eb/e2/02652007469263fe1466e98439831d65d4ca80ea1a2df29abecedf7e47b7/pywin32-308-cp311-cp311-win32.whl", hash = "sha256:5d8c8015b24a7d6855b1550d8e660d8daa09983c80e5daf89a273e5c6fb5095a", size = 5928156 }, - { url = "https://files.pythonhosted.org/packages/48/ef/f4fb45e2196bc7ffe09cad0542d9aff66b0e33f6c0954b43e49c33cad7bd/pywin32-308-cp311-cp311-win_amd64.whl", hash = "sha256:575621b90f0dc2695fec346b2d6302faebd4f0f45c05ea29404cefe35d89442b", size = 6559559 }, - { url = "https://files.pythonhosted.org/packages/79/ef/68bb6aa865c5c9b11a35771329e95917b5559845bd75b65549407f9fc6b4/pywin32-308-cp311-cp311-win_arm64.whl", hash = "sha256:100a5442b7332070983c4cd03f2e906a5648a5104b8a7f50175f7906efd16bb6", size = 7972495 }, - { url = "https://files.pythonhosted.org/packages/00/7c/d00d6bdd96de4344e06c4afbf218bc86b54436a94c01c71a8701f613aa56/pywin32-308-cp312-cp312-win32.whl", hash = "sha256:587f3e19696f4bf96fde9d8a57cec74a57021ad5f204c9e627e15c33ff568897", size = 5939729 }, - { url = "https://files.pythonhosted.org/packages/21/27/0c8811fbc3ca188f93b5354e7c286eb91f80a53afa4e11007ef661afa746/pywin32-308-cp312-cp312-win_amd64.whl", hash = "sha256:00b3e11ef09ede56c6a43c71f2d31857cf7c54b0ab6e78ac659497abd2834f47", size = 6543015 }, - { url = "https://files.pythonhosted.org/packages/9d/0f/d40f8373608caed2255781a3ad9a51d03a594a1248cd632d6a298daca693/pywin32-308-cp312-cp312-win_arm64.whl", hash = "sha256:9b4de86c8d909aed15b7011182c8cab38c8850de36e6afb1f0db22b8959e3091", size = 7976033 }, + { url = "https://files.pythonhosted.org/packages/7c/af/449a6a91e5d6db51420875c54f6aff7c97a86a3b13a0b4f1a5c13b988de3/pywin32-311-cp311-cp311-win32.whl", hash = "sha256:184eb5e436dea364dcd3d2316d577d625c0351bf237c4e9a5fabbcfa5a58b151", size = 8697031, upload-time = "2025-07-14T20:13:13.266Z" }, + { url = "https://files.pythonhosted.org/packages/51/8f/9bb81dd5bb77d22243d33c8397f09377056d5c687aa6d4042bea7fbf8364/pywin32-311-cp311-cp311-win_amd64.whl", hash = "sha256:3ce80b34b22b17ccbd937a6e78e7225d80c52f5ab9940fe0506a1a16f3dab503", size = 9508308, upload-time = "2025-07-14T20:13:15.147Z" }, + { url = "https://files.pythonhosted.org/packages/44/7b/9c2ab54f74a138c491aba1b1cd0795ba61f144c711daea84a88b63dc0f6c/pywin32-311-cp311-cp311-win_arm64.whl", hash = "sha256:a733f1388e1a842abb67ffa8e7aad0e70ac519e09b0f6a784e65a136ec7cefd2", size = 8703930, upload-time = "2025-07-14T20:13:16.945Z" }, + { url = "https://files.pythonhosted.org/packages/e7/ab/01ea1943d4eba0f850c3c61e78e8dd59757ff815ff3ccd0a84de5f541f42/pywin32-311-cp312-cp312-win32.whl", hash = "sha256:750ec6e621af2b948540032557b10a2d43b0cee2ae9758c54154d711cc852d31", size = 8706543, upload-time = "2025-07-14T20:13:20.765Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a8/a0e8d07d4d051ec7502cd58b291ec98dcc0c3fff027caad0470b72cfcc2f/pywin32-311-cp312-cp312-win_amd64.whl", hash = "sha256:b8c095edad5c211ff31c05223658e71bf7116daa0ecf3ad85f3201ea3190d067", size = 9495040, upload-time = "2025-07-14T20:13:22.543Z" }, + { url = "https://files.pythonhosted.org/packages/ba/3a/2ae996277b4b50f17d61f0603efd8253cb2d79cc7ae159468007b586396d/pywin32-311-cp312-cp312-win_arm64.whl", hash = "sha256:e286f46a9a39c4a18b319c28f59b61de793654af2f395c102b4f819e584b5852", size = 8710102, upload-time = "2025-07-14T20:13:24.682Z" }, + { url = "https://files.pythonhosted.org/packages/a5/be/3fd5de0979fcb3994bfee0d65ed8ca9506a8a1260651b86174f6a86f52b3/pywin32-311-cp313-cp313-win32.whl", hash = "sha256:f95ba5a847cba10dd8c4d8fefa9f2a6cf283b8b88ed6178fa8a6c1ab16054d0d", size = 8705700, upload-time = "2025-07-14T20:13:26.471Z" }, + { url = "https://files.pythonhosted.org/packages/e3/28/e0a1909523c6890208295a29e05c2adb2126364e289826c0a8bc7297bd5c/pywin32-311-cp313-cp313-win_amd64.whl", hash = "sha256:718a38f7e5b058e76aee1c56ddd06908116d35147e133427e59a3983f703a20d", size = 9494700, upload-time = "2025-07-14T20:13:28.243Z" }, + { url = "https://files.pythonhosted.org/packages/04/bf/90339ac0f55726dce7d794e6d79a18a91265bdf3aa70b6b9ca52f35e022a/pywin32-311-cp313-cp313-win_arm64.whl", hash = "sha256:7b4075d959648406202d92a2310cb990fea19b535c7f4a78d3f5e10b926eeb8a", size = 8709318, upload-time = "2025-07-14T20:13:30.348Z" }, ] [[package]] name = "pywinpty" -version = "2.0.14" +version = "3.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f1/82/90f8750423cba4b9b6c842df227609fb60704482d7abf6dd47e2babc055a/pywinpty-2.0.14.tar.gz", hash = "sha256:18bd9529e4a5daf2d9719aa17788ba6013e594ae94c5a0c27e83df3278b0660e", size = 27769 } +sdist = { url = "https://files.pythonhosted.org/packages/06/df/429cc505dc5f77ab0612c4b60bca2e3dcc81f6c321844ee017d6dc0f4a95/pywinpty-3.0.0.tar.gz", hash = "sha256:68f70e68a9f0766ffdea3fc500351cb7b9b012bcb8239a411f7ff0fc8f86dcb1", size = 28551, upload-time = "2025-08-12T20:33:46.506Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/07/09/56376af256eab8cc5f8982a3b138d387136eca27fa1a8a68660e8ed59e4b/pywinpty-2.0.14-cp310-none-win_amd64.whl", hash = "sha256:0b149c2918c7974f575ba79f5a4aad58bd859a52fa9eb1296cc22aa412aa411f", size = 1397115 }, - { url = "https://files.pythonhosted.org/packages/be/e2/af1a99c0432e4e58c9ac8e334ee191790ec9793d33559189b9d2069bdc1d/pywinpty-2.0.14-cp311-none-win_amd64.whl", hash = "sha256:cf2a43ac7065b3e0dc8510f8c1f13a75fb8fde805efa3b8cff7599a1ef497bc7", size = 1397223 }, - { url = "https://files.pythonhosted.org/packages/ad/79/759ae767a3b78d340446efd54dd1fe4f7dafa4fc7be96ed757e44bcdba54/pywinpty-2.0.14-cp312-none-win_amd64.whl", hash = "sha256:55dad362ef3e9408ade68fd173e4f9032b3ce08f68cfe7eacb2c263ea1179737", size = 1397207 }, + { url = "https://files.pythonhosted.org/packages/d6/34/30727e8a97709f5033277457df9a293ccddf34d6eb7528e6a1e910265307/pywinpty-3.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:29daa71ac5dcbe1496ef99f4cde85a732b1f0a3b71405d42177dbcf9ee405e5a", size = 2051048, upload-time = "2025-08-12T20:37:18.488Z" }, + { url = "https://files.pythonhosted.org/packages/76/d9/bd2249815c305ef8f879b326db1fe1effc8e5f22bd88e522b4b55231aa6f/pywinpty-3.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:1e0c4b01e5b03b1531d7c5d0e044b8c66dd0288c6d2b661820849f2a8d91aec3", size = 2051564, upload-time = "2025-08-12T20:37:09.128Z" }, + { url = "https://files.pythonhosted.org/packages/e2/77/358b1a97c1d0714f288949372ec64a70884a7eceb3f887042b9ae0bea388/pywinpty-3.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:828cbe756b7e3d25d886fbd5691a1d523cd59c5fb79286bb32bb75c5221e7ba1", size = 2050856, upload-time = "2025-08-12T20:36:09.117Z" }, + { url = "https://files.pythonhosted.org/packages/8f/6c/4249cfb4eb4fdad2c76bc96db0642a40111847c375b92e5b9f4bf289ddd6/pywinpty-3.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:de0cbe27b96e5a2cebd86c4a6b8b4139f978d9c169d44a8edc7e30e88e5d7a69", size = 2050082, upload-time = "2025-08-12T20:36:28.591Z" }, ] [[package]] name = "pyyaml" version = "6.0.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9b/95/a3fac87cb7158e231b5a6012e438c647e1a87f09f8e0d123acec8ab8bf71/PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", size = 184199 }, - { url = "https://files.pythonhosted.org/packages/c7/7a/68bd47624dab8fd4afbfd3c48e3b79efe09098ae941de5b58abcbadff5cb/PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", size = 171758 }, - { url = "https://files.pythonhosted.org/packages/49/ee/14c54df452143b9ee9f0f29074d7ca5516a36edb0b4cc40c3f280131656f/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", size = 718463 }, - { url = "https://files.pythonhosted.org/packages/4d/61/de363a97476e766574650d742205be468921a7b532aa2499fcd886b62530/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", size = 719280 }, - { url = "https://files.pythonhosted.org/packages/6b/4e/1523cb902fd98355e2e9ea5e5eb237cbc5f3ad5f3075fa65087aa0ecb669/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", size = 751239 }, - { url = "https://files.pythonhosted.org/packages/b7/33/5504b3a9a4464893c32f118a9cc045190a91637b119a9c881da1cf6b7a72/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", size = 695802 }, - { url = "https://files.pythonhosted.org/packages/5c/20/8347dcabd41ef3a3cdc4f7b7a2aff3d06598c8779faa189cdbf878b626a4/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", size = 720527 }, - { url = "https://files.pythonhosted.org/packages/be/aa/5afe99233fb360d0ff37377145a949ae258aaab831bde4792b32650a4378/PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", size = 144052 }, - { url = "https://files.pythonhosted.org/packages/b5/84/0fa4b06f6d6c958d207620fc60005e241ecedceee58931bb20138e1e5776/PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", size = 161774 }, - { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612 }, - { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040 }, - { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829 }, - { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167 }, - { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952 }, - { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301 }, - { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638 }, - { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850 }, - { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980 }, - { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873 }, - { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302 }, - { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154 }, - { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223 }, - { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542 }, - { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164 }, - { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611 }, - { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591 }, - { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338 }, +sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612, upload-time = "2024-08-06T20:32:03.408Z" }, + { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040, upload-time = "2024-08-06T20:32:04.926Z" }, + { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829, upload-time = "2024-08-06T20:32:06.459Z" }, + { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167, upload-time = "2024-08-06T20:32:08.338Z" }, + { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952, upload-time = "2024-08-06T20:32:14.124Z" }, + { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301, upload-time = "2024-08-06T20:32:16.17Z" }, + { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638, upload-time = "2024-08-06T20:32:18.555Z" }, + { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850, upload-time = "2024-08-06T20:32:19.889Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980, upload-time = "2024-08-06T20:32:21.273Z" }, + { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873, upload-time = "2024-08-06T20:32:25.131Z" }, + { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302, upload-time = "2024-08-06T20:32:26.511Z" }, + { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154, upload-time = "2024-08-06T20:32:28.363Z" }, + { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223, upload-time = "2024-08-06T20:32:30.058Z" }, + { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542, upload-time = "2024-08-06T20:32:31.881Z" }, + { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164, upload-time = "2024-08-06T20:32:37.083Z" }, + { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611, upload-time = "2024-08-06T20:32:38.898Z" }, + { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591, upload-time = "2024-08-06T20:32:40.241Z" }, + { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338, upload-time = "2024-08-06T20:32:41.93Z" }, + { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" }, + { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" }, + { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" }, + { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" }, + { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" }, + { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" }, + { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" }, + { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" }, + { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" }, ] [[package]] name = "pyzmq" -version = "26.2.0" +version = "27.0.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "implementation_name == 'pypy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fd/05/bed626b9f7bb2322cdbbf7b4bd8f54b1b617b0d2ab2d3547d6e39428a48e/pyzmq-26.2.0.tar.gz", hash = "sha256:070672c258581c8e4f640b5159297580a9974b026043bd4ab0470be9ed324f1f", size = 271975 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1f/a8/9837c39aba390eb7d01924ace49d761c8dbe7bc2d6082346d00c8332e431/pyzmq-26.2.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:ddf33d97d2f52d89f6e6e7ae66ee35a4d9ca6f36eda89c24591b0c40205a3629", size = 1340058 }, - { url = "https://files.pythonhosted.org/packages/a2/1f/a006f2e8e4f7d41d464272012695da17fb95f33b54342612a6890da96ff6/pyzmq-26.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dacd995031a01d16eec825bf30802fceb2c3791ef24bcce48fa98ce40918c27b", size = 1008818 }, - { url = "https://files.pythonhosted.org/packages/b6/09/b51b6683fde5ca04593a57bbe81788b6b43114d8f8ee4e80afc991e14760/pyzmq-26.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89289a5ee32ef6c439086184529ae060c741334b8970a6855ec0b6ad3ff28764", size = 673199 }, - { url = "https://files.pythonhosted.org/packages/c9/78/486f3e2e824f3a645238332bf5a4c4b4477c3063033a27c1e4052358dee2/pyzmq-26.2.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5506f06d7dc6ecf1efacb4a013b1f05071bb24b76350832c96449f4a2d95091c", size = 911762 }, - { url = "https://files.pythonhosted.org/packages/5e/3b/2eb1667c9b866f53e76ee8b0c301b0469745a23bd5a87b7ee3d5dd9eb6e5/pyzmq-26.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ea039387c10202ce304af74def5021e9adc6297067f3441d348d2b633e8166a", size = 868773 }, - { url = "https://files.pythonhosted.org/packages/16/29/ca99b4598a9dc7e468b5417eda91f372b595be1e3eec9b7cbe8e5d3584e8/pyzmq-26.2.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a2224fa4a4c2ee872886ed00a571f5e967c85e078e8e8c2530a2fb01b3309b88", size = 868834 }, - { url = "https://files.pythonhosted.org/packages/ad/e5/9efaeb1d2f4f8c50da04144f639b042bc52869d3a206d6bf672ab3522163/pyzmq-26.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:28ad5233e9c3b52d76196c696e362508959741e1a005fb8fa03b51aea156088f", size = 1202861 }, - { url = "https://files.pythonhosted.org/packages/c3/62/c721b5608a8ac0a69bb83cbb7d07a56f3ff00b3991a138e44198a16f94c7/pyzmq-26.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:1c17211bc037c7d88e85ed8b7d8f7e52db6dc8eca5590d162717c654550f7282", size = 1515304 }, - { url = "https://files.pythonhosted.org/packages/87/84/e8bd321aa99b72f48d4606fc5a0a920154125bd0a4608c67eab742dab087/pyzmq-26.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b8f86dd868d41bea9a5f873ee13bf5551c94cf6bc51baebc6f85075971fe6eea", size = 1414712 }, - { url = "https://files.pythonhosted.org/packages/cd/cd/420e3fd1ac6977b008b72e7ad2dae6350cc84d4c5027fc390b024e61738f/pyzmq-26.2.0-cp310-cp310-win32.whl", hash = "sha256:46a446c212e58456b23af260f3d9fb785054f3e3653dbf7279d8f2b5546b21c2", size = 578113 }, - { url = "https://files.pythonhosted.org/packages/5c/57/73930d56ed45ae0cb4946f383f985c855c9b3d4063f26416998f07523c0e/pyzmq-26.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:49d34ab71db5a9c292a7644ce74190b1dd5a3475612eefb1f8be1d6961441971", size = 641631 }, - { url = "https://files.pythonhosted.org/packages/61/d2/ae6ac5c397f1ccad59031c64beaafce7a0d6182e0452cc48f1c9c87d2dd0/pyzmq-26.2.0-cp310-cp310-win_arm64.whl", hash = "sha256:bfa832bfa540e5b5c27dcf5de5d82ebc431b82c453a43d141afb1e5d2de025fa", size = 543528 }, - { url = "https://files.pythonhosted.org/packages/12/20/de7442172f77f7c96299a0ac70e7d4fb78cd51eca67aa2cf552b66c14196/pyzmq-26.2.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:8f7e66c7113c684c2b3f1c83cdd3376103ee0ce4c49ff80a648643e57fb22218", size = 1340639 }, - { url = "https://files.pythonhosted.org/packages/98/4d/5000468bd64c7910190ed0a6c76a1ca59a68189ec1f007c451dc181a22f4/pyzmq-26.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3a495b30fc91db2db25120df5847d9833af237546fd59170701acd816ccc01c4", size = 1008710 }, - { url = "https://files.pythonhosted.org/packages/e1/bf/c67fd638c2f9fbbab8090a3ee779370b97c82b84cc12d0c498b285d7b2c0/pyzmq-26.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77eb0968da535cba0470a5165468b2cac7772cfb569977cff92e240f57e31bef", size = 673129 }, - { url = "https://files.pythonhosted.org/packages/86/94/99085a3f492aa538161cbf27246e8886ff850e113e0c294a5b8245f13b52/pyzmq-26.2.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ace4f71f1900a548f48407fc9be59c6ba9d9aaf658c2eea6cf2779e72f9f317", size = 910107 }, - { url = "https://files.pythonhosted.org/packages/31/1d/346809e8a9b999646d03f21096428453465b1bca5cd5c64ecd048d9ecb01/pyzmq-26.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:92a78853d7280bffb93df0a4a6a2498cba10ee793cc8076ef797ef2f74d107cf", size = 867960 }, - { url = "https://files.pythonhosted.org/packages/ab/68/6fb6ae5551846ad5beca295b7bca32bf0a7ce19f135cb30e55fa2314e6b6/pyzmq-26.2.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:689c5d781014956a4a6de61d74ba97b23547e431e9e7d64f27d4922ba96e9d6e", size = 869204 }, - { url = "https://files.pythonhosted.org/packages/0f/f9/18417771dee223ccf0f48e29adf8b4e25ba6d0e8285e33bcbce078070bc3/pyzmq-26.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0aca98bc423eb7d153214b2df397c6421ba6373d3397b26c057af3c904452e37", size = 1203351 }, - { url = "https://files.pythonhosted.org/packages/e0/46/f13e67fe0d4f8a2315782cbad50493de6203ea0d744610faf4d5f5b16e90/pyzmq-26.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1f3496d76b89d9429a656293744ceca4d2ac2a10ae59b84c1da9b5165f429ad3", size = 1514204 }, - { url = "https://files.pythonhosted.org/packages/50/11/ddcf7343b7b7a226e0fc7b68cbf5a5bb56291fac07f5c3023bb4c319ebb4/pyzmq-26.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5c2b3bfd4b9689919db068ac6c9911f3fcb231c39f7dd30e3138be94896d18e6", size = 1414339 }, - { url = "https://files.pythonhosted.org/packages/01/14/1c18d7d5b7be2708f513f37c61bfadfa62161c10624f8733f1c8451b3509/pyzmq-26.2.0-cp311-cp311-win32.whl", hash = "sha256:eac5174677da084abf378739dbf4ad245661635f1600edd1221f150b165343f4", size = 576928 }, - { url = "https://files.pythonhosted.org/packages/3b/1b/0a540edd75a41df14ec416a9a500b9fec66e554aac920d4c58fbd5756776/pyzmq-26.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:5a509df7d0a83a4b178d0f937ef14286659225ef4e8812e05580776c70e155d5", size = 642317 }, - { url = "https://files.pythonhosted.org/packages/98/77/1cbfec0358078a4c5add529d8a70892db1be900980cdb5dd0898b3d6ab9d/pyzmq-26.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:c0e6091b157d48cbe37bd67233318dbb53e1e6327d6fc3bb284afd585d141003", size = 543834 }, - { url = "https://files.pythonhosted.org/packages/28/2f/78a766c8913ad62b28581777ac4ede50c6d9f249d39c2963e279524a1bbe/pyzmq-26.2.0-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:ded0fc7d90fe93ae0b18059930086c51e640cdd3baebdc783a695c77f123dcd9", size = 1343105 }, - { url = "https://files.pythonhosted.org/packages/b7/9c/4b1e2d3d4065be715e007fe063ec7885978fad285f87eae1436e6c3201f4/pyzmq-26.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:17bf5a931c7f6618023cdacc7081f3f266aecb68ca692adac015c383a134ca52", size = 1008365 }, - { url = "https://files.pythonhosted.org/packages/4f/ef/5a23ec689ff36d7625b38d121ef15abfc3631a9aecb417baf7a4245e4124/pyzmq-26.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55cf66647e49d4621a7e20c8d13511ef1fe1efbbccf670811864452487007e08", size = 665923 }, - { url = "https://files.pythonhosted.org/packages/ae/61/d436461a47437d63c6302c90724cf0981883ec57ceb6073873f32172d676/pyzmq-26.2.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4661c88db4a9e0f958c8abc2b97472e23061f0bc737f6f6179d7a27024e1faa5", size = 903400 }, - { url = "https://files.pythonhosted.org/packages/47/42/fc6d35ecefe1739a819afaf6f8e686f7f02a4dd241c78972d316f403474c/pyzmq-26.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea7f69de383cb47522c9c208aec6dd17697db7875a4674c4af3f8cfdac0bdeae", size = 860034 }, - { url = "https://files.pythonhosted.org/packages/07/3b/44ea6266a6761e9eefaa37d98fabefa112328808ac41aa87b4bbb668af30/pyzmq-26.2.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:7f98f6dfa8b8ccaf39163ce872bddacca38f6a67289116c8937a02e30bbe9711", size = 860579 }, - { url = "https://files.pythonhosted.org/packages/38/6f/4df2014ab553a6052b0e551b37da55166991510f9e1002c89cab7ce3b3f2/pyzmq-26.2.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e3e0210287329272539eea617830a6a28161fbbd8a3271bf4150ae3e58c5d0e6", size = 1196246 }, - { url = "https://files.pythonhosted.org/packages/38/9d/ee240fc0c9fe9817f0c9127a43238a3e28048795483c403cc10720ddef22/pyzmq-26.2.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6b274e0762c33c7471f1a7471d1a2085b1a35eba5cdc48d2ae319f28b6fc4de3", size = 1507441 }, - { url = "https://files.pythonhosted.org/packages/85/4f/01711edaa58d535eac4a26c294c617c9a01f09857c0ce191fd574d06f359/pyzmq-26.2.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:29c6a4635eef69d68a00321e12a7d2559fe2dfccfa8efae3ffb8e91cd0b36a8b", size = 1406498 }, - { url = "https://files.pythonhosted.org/packages/07/18/907134c85c7152f679ed744e73e645b365f3ad571f38bdb62e36f347699a/pyzmq-26.2.0-cp312-cp312-win32.whl", hash = "sha256:989d842dc06dc59feea09e58c74ca3e1678c812a4a8a2a419046d711031f69c7", size = 575533 }, - { url = "https://files.pythonhosted.org/packages/ce/2c/a6f4a20202a4d3c582ad93f95ee78d79bbdc26803495aec2912b17dbbb6c/pyzmq-26.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:2a50625acdc7801bc6f74698c5c583a491c61d73c6b7ea4dee3901bb99adb27a", size = 637768 }, - { url = "https://files.pythonhosted.org/packages/5f/0e/eb16ff731632d30554bf5af4dbba3ffcd04518219d82028aea4ae1b02ca5/pyzmq-26.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:4d29ab8592b6ad12ebbf92ac2ed2bedcfd1cec192d8e559e2e099f648570e19b", size = 540675 }, - { url = "https://files.pythonhosted.org/packages/53/fb/36b2b2548286e9444e52fcd198760af99fd89102b5be50f0660fcfe902df/pyzmq-26.2.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:706e794564bec25819d21a41c31d4df2d48e1cc4b061e8d345d7fb4dd3e94072", size = 906955 }, - { url = "https://files.pythonhosted.org/packages/77/8f/6ce54f8979a01656e894946db6299e2273fcee21c8e5fa57c6295ef11f57/pyzmq-26.2.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b435f2753621cd36e7c1762156815e21c985c72b19135dac43a7f4f31d28dd1", size = 565701 }, - { url = "https://files.pythonhosted.org/packages/ee/1c/bf8cd66730a866b16db8483286078892b7f6536f8c389fb46e4beba0a970/pyzmq-26.2.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:160c7e0a5eb178011e72892f99f918c04a131f36056d10d9c1afb223fc952c2d", size = 794312 }, - { url = "https://files.pythonhosted.org/packages/71/43/91fa4ff25bbfdc914ab6bafa0f03241d69370ef31a761d16bb859f346582/pyzmq-26.2.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c4a71d5d6e7b28a47a394c0471b7e77a0661e2d651e7ae91e0cab0a587859ca", size = 752775 }, - { url = "https://files.pythonhosted.org/packages/ec/d2/3b2ab40f455a256cb6672186bea95cd97b459ce4594050132d71e76f0d6f/pyzmq-26.2.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:90412f2db8c02a3864cbfc67db0e3dcdbda336acf1c469526d3e869394fe001c", size = 550762 }, +sdist = { url = "https://files.pythonhosted.org/packages/f8/66/159f38d184f08b5f971b467f87b1ab142ab1320d5200825c824b32b84b66/pyzmq-27.0.2.tar.gz", hash = "sha256:b398dd713b18de89730447347e96a0240225e154db56e35b6bb8447ffdb07798", size = 281440, upload-time = "2025-08-21T04:23:26.334Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/73/034429ab0f4316bf433eb6c20c3f49d1dc13b2ed4e4d951b283d300a0f35/pyzmq-27.0.2-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:063845960df76599ad4fad69fa4d884b3ba38304272104fdcd7e3af33faeeb1d", size = 1333169, upload-time = "2025-08-21T04:21:12.483Z" }, + { url = "https://files.pythonhosted.org/packages/35/02/c42b3b526eb03a570c889eea85a5602797f800a50ba8b09ddbf7db568b78/pyzmq-27.0.2-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:845a35fb21b88786aeb38af8b271d41ab0967985410f35411a27eebdc578a076", size = 909176, upload-time = "2025-08-21T04:21:13.835Z" }, + { url = "https://files.pythonhosted.org/packages/1b/35/a1c0b988fabbdf2dc5fe94b7c2bcfd61e3533e5109297b8e0daf1d7a8d2d/pyzmq-27.0.2-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:515d20b5c3c86db95503faa989853a8ab692aab1e5336db011cd6d35626c4cb1", size = 668972, upload-time = "2025-08-21T04:21:15.315Z" }, + { url = "https://files.pythonhosted.org/packages/a0/63/908ac865da32ceaeecea72adceadad28ca25b23a2ca5ff018e5bff30116f/pyzmq-27.0.2-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:862aedec0b0684a5050cdb5ec13c2da96d2f8dffda48657ed35e312a4e31553b", size = 856962, upload-time = "2025-08-21T04:21:16.652Z" }, + { url = "https://files.pythonhosted.org/packages/2f/5a/90b3cc20b65cdf9391896fcfc15d8db21182eab810b7ea05a2986912fbe2/pyzmq-27.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2cb5bcfc51c7a4fce335d3bc974fd1d6a916abbcdd2b25f6e89d37b8def25f57", size = 1657712, upload-time = "2025-08-21T04:21:18.666Z" }, + { url = "https://files.pythonhosted.org/packages/c4/3c/32a5a80f9be4759325b8d7b22ce674bb87e586b4c80c6a9d77598b60d6f0/pyzmq-27.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:38ff75b2a36e3a032e9fef29a5871e3e1301a37464e09ba364e3c3193f62982a", size = 2035054, upload-time = "2025-08-21T04:21:20.073Z" }, + { url = "https://files.pythonhosted.org/packages/13/61/71084fe2ff2d7dc5713f8740d735336e87544845dae1207a8e2e16d9af90/pyzmq-27.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7a5709abe8d23ca158a9d0a18c037f4193f5b6afeb53be37173a41e9fb885792", size = 1894010, upload-time = "2025-08-21T04:21:21.96Z" }, + { url = "https://files.pythonhosted.org/packages/cb/6b/77169cfb13b696e50112ca496b2ed23c4b7d8860a1ec0ff3e4b9f9926221/pyzmq-27.0.2-cp311-cp311-win32.whl", hash = "sha256:47c5dda2018c35d87be9b83de0890cb92ac0791fd59498847fc4eca6ff56671d", size = 566819, upload-time = "2025-08-21T04:21:23.31Z" }, + { url = "https://files.pythonhosted.org/packages/37/cd/86c4083e0f811f48f11bc0ddf1e7d13ef37adfd2fd4f78f2445f1cc5dec0/pyzmq-27.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:f54ca3e98f8f4d23e989c7d0edcf9da7a514ff261edaf64d1d8653dd5feb0a8b", size = 633264, upload-time = "2025-08-21T04:21:24.761Z" }, + { url = "https://files.pythonhosted.org/packages/a0/69/5b8bb6a19a36a569fac02153a9e083738785892636270f5f68a915956aea/pyzmq-27.0.2-cp311-cp311-win_arm64.whl", hash = "sha256:2ef3067cb5b51b090fb853f423ad7ed63836ec154374282780a62eb866bf5768", size = 559316, upload-time = "2025-08-21T04:21:26.1Z" }, + { url = "https://files.pythonhosted.org/packages/68/69/b3a729e7b03e412bee2b1823ab8d22e20a92593634f664afd04c6c9d9ac0/pyzmq-27.0.2-cp312-abi3-macosx_10_15_universal2.whl", hash = "sha256:5da05e3c22c95e23bfc4afeee6ff7d4be9ff2233ad6cb171a0e8257cd46b169a", size = 1305910, upload-time = "2025-08-21T04:21:27.609Z" }, + { url = "https://files.pythonhosted.org/packages/15/b7/f6a6a285193d489b223c340b38ee03a673467cb54914da21c3d7849f1b10/pyzmq-27.0.2-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:4e4520577971d01d47e2559bb3175fce1be9103b18621bf0b241abe0a933d040", size = 895507, upload-time = "2025-08-21T04:21:29.005Z" }, + { url = "https://files.pythonhosted.org/packages/17/e6/c4ed2da5ef9182cde1b1f5d0051a986e76339d71720ec1a00be0b49275ad/pyzmq-27.0.2-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:56d7de7bf73165b90bd25a8668659ccb134dd28449116bf3c7e9bab5cf8a8ec9", size = 652670, upload-time = "2025-08-21T04:21:30.71Z" }, + { url = "https://files.pythonhosted.org/packages/0e/66/d781ab0636570d32c745c4e389b1c6b713115905cca69ab6233508622edd/pyzmq-27.0.2-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:340e7cddc32f147c6c00d116a3f284ab07ee63dbd26c52be13b590520434533c", size = 840581, upload-time = "2025-08-21T04:21:32.008Z" }, + { url = "https://files.pythonhosted.org/packages/a6/df/f24790caf565d72544f5c8d8500960b9562c1dc848d6f22f3c7e122e73d4/pyzmq-27.0.2-cp312-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ba95693f9df8bb4a9826464fb0fe89033936f35fd4a8ff1edff09a473570afa0", size = 1641931, upload-time = "2025-08-21T04:21:33.371Z" }, + { url = "https://files.pythonhosted.org/packages/65/65/77d27b19fc5e845367f9100db90b9fce924f611b14770db480615944c9c9/pyzmq-27.0.2-cp312-abi3-musllinux_1_2_i686.whl", hash = "sha256:ca42a6ce2d697537da34f77a1960d21476c6a4af3e539eddb2b114c3cf65a78c", size = 2021226, upload-time = "2025-08-21T04:21:35.301Z" }, + { url = "https://files.pythonhosted.org/packages/5b/65/1ed14421ba27a4207fa694772003a311d1142b7f543179e4d1099b7eb746/pyzmq-27.0.2-cp312-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3e44e665d78a07214b2772ccbd4b9bcc6d848d7895f1b2d7653f047b6318a4f6", size = 1878047, upload-time = "2025-08-21T04:21:36.749Z" }, + { url = "https://files.pythonhosted.org/packages/dd/dc/e578549b89b40dc78a387ec471c2a360766690c0a045cd8d1877d401012d/pyzmq-27.0.2-cp312-abi3-win32.whl", hash = "sha256:272d772d116615397d2be2b1417b3b8c8bc8671f93728c2f2c25002a4530e8f6", size = 558757, upload-time = "2025-08-21T04:21:38.2Z" }, + { url = "https://files.pythonhosted.org/packages/b5/89/06600980aefcc535c758414da969f37a5194ea4cdb73b745223f6af3acfb/pyzmq-27.0.2-cp312-abi3-win_amd64.whl", hash = "sha256:734be4f44efba0aa69bf5f015ed13eb69ff29bf0d17ea1e21588b095a3147b8e", size = 619281, upload-time = "2025-08-21T04:21:39.909Z" }, + { url = "https://files.pythonhosted.org/packages/30/84/df8a5c089552d17c9941d1aea4314b606edf1b1622361dae89aacedc6467/pyzmq-27.0.2-cp312-abi3-win_arm64.whl", hash = "sha256:41f0bd56d9279392810950feb2785a419c2920bbf007fdaaa7f4a07332ae492d", size = 552680, upload-time = "2025-08-21T04:21:41.571Z" }, + { url = "https://files.pythonhosted.org/packages/b4/7b/b79e976508517ab80dc800f7021ef1fb602a6d55e4caa2d47fb3dca5d8b6/pyzmq-27.0.2-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:7f01118133427cd7f34ee133b5098e2af5f70303fa7519785c007bca5aa6f96a", size = 1122259, upload-time = "2025-08-21T04:21:43.063Z" }, + { url = "https://files.pythonhosted.org/packages/2b/1c/777217b9940ebcb7e71c924184ca5f31e410580a58d9fd93798589f0d31c/pyzmq-27.0.2-cp313-cp313-android_24_x86_64.whl", hash = "sha256:e4b860edf6379a7234ccbb19b4ed2c57e3ff569c3414fadfb49ae72b61a8ef07", size = 1156113, upload-time = "2025-08-21T04:21:44.566Z" }, + { url = "https://files.pythonhosted.org/packages/59/7d/654657a4c6435f41538182e71b61eac386a789a2bbb6f30171915253a9a7/pyzmq-27.0.2-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:cb77923ea163156da14295c941930bd525df0d29c96c1ec2fe3c3806b1e17cb3", size = 1341437, upload-time = "2025-08-21T04:21:46.019Z" }, + { url = "https://files.pythonhosted.org/packages/20/a0/5ed7710037f9c096017adc748bcb1698674a2d297f8b9422d38816f7b56a/pyzmq-27.0.2-cp313-cp313t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:61678b7407b04df8f9423f188156355dc94d0fb52d360ae79d02ed7e0d431eea", size = 897888, upload-time = "2025-08-21T04:21:47.362Z" }, + { url = "https://files.pythonhosted.org/packages/2c/8a/6e4699a60931c17e7406641d201d7f2c121e2a38979bc83226a6d8f1ba32/pyzmq-27.0.2-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e3c824b70925963bdc8e39a642672c15ffaa67e7d4b491f64662dd56d6271263", size = 660727, upload-time = "2025-08-21T04:21:48.734Z" }, + { url = "https://files.pythonhosted.org/packages/7b/d8/d761e438c186451bd89ce63a665cde5690c084b61cd8f5d7b51e966e875a/pyzmq-27.0.2-cp313-cp313t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c4833e02fcf2751975457be1dfa2f744d4d09901a8cc106acaa519d868232175", size = 848136, upload-time = "2025-08-21T04:21:50.416Z" }, + { url = "https://files.pythonhosted.org/packages/43/f1/a0f31684efdf3eb92f46b7dd2117e752208115e89d278f8ca5f413c5bb85/pyzmq-27.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b18045668d09cf0faa44918af2a67f0dbbef738c96f61c2f1b975b1ddb92ccfc", size = 1650402, upload-time = "2025-08-21T04:21:52.235Z" }, + { url = "https://files.pythonhosted.org/packages/41/fd/0d7f2a1732812df02c85002770da4a7864c79b210084bcdab01ea57e8d92/pyzmq-27.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:bbbb7e2f3ac5a22901324e7b086f398b8e16d343879a77b15ca3312e8cd8e6d5", size = 2024587, upload-time = "2025-08-21T04:21:54.07Z" }, + { url = "https://files.pythonhosted.org/packages/f1/73/358be69e279a382dd09e46dda29df8446365cddee4f79ef214e71e5b2b5a/pyzmq-27.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:b751914a73604d40d88a061bab042a11d4511b3ddbb7624cd83c39c8a498564c", size = 1885493, upload-time = "2025-08-21T04:21:55.588Z" }, + { url = "https://files.pythonhosted.org/packages/c5/7b/e9951ad53b3dfed8cfb4c2cfd6e0097c9b454e5c0d0e6df5f2b60d7c8c3d/pyzmq-27.0.2-cp313-cp313t-win32.whl", hash = "sha256:3e8f833dd82af11db5321c414638045c70f61009f72dd61c88db4a713c1fb1d2", size = 574934, upload-time = "2025-08-21T04:21:57.52Z" }, + { url = "https://files.pythonhosted.org/packages/55/33/1a7fc3a92f2124a63e6e2a6afa0af471a5c0c713e776b476d4eda5111b13/pyzmq-27.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:5b45153cb8eadcab14139970643a84f7a7b08dda541fbc1f6f4855c49334b549", size = 640932, upload-time = "2025-08-21T04:21:59.527Z" }, + { url = "https://files.pythonhosted.org/packages/2a/52/2598a94ac251a7c83f3887866225eea1952b0d4463a68df5032eb00ff052/pyzmq-27.0.2-cp313-cp313t-win_arm64.whl", hash = "sha256:86898f5c9730df23427c1ee0097d8aa41aa5f89539a79e48cd0d2c22d059f1b7", size = 561315, upload-time = "2025-08-21T04:22:01.295Z" }, + { url = "https://files.pythonhosted.org/packages/c7/60/027d0032a1e3b1aabcef0e309b9ff8a4099bdd5a60ab38b36a676ff2bd7b/pyzmq-27.0.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e297784aea724294fe95e442e39a4376c2f08aa4fae4161c669f047051e31b02", size = 836007, upload-time = "2025-08-21T04:23:00.447Z" }, + { url = "https://files.pythonhosted.org/packages/25/20/2ed1e6168aaea323df9bb2c451309291f53ba3af372ffc16edd4ce15b9e5/pyzmq-27.0.2-pp311-pypy311_pp73-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:e3659a79ded9745bc9c2aef5b444ac8805606e7bc50d2d2eb16dc3ab5483d91f", size = 799932, upload-time = "2025-08-21T04:23:02.052Z" }, + { url = "https://files.pythonhosted.org/packages/fd/25/5c147307de546b502c9373688ce5b25dc22288d23a1ebebe5d587bf77610/pyzmq-27.0.2-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3dba49ff037d02373a9306b58d6c1e0be031438f822044e8767afccfdac4c6b", size = 567459, upload-time = "2025-08-21T04:23:03.593Z" }, + { url = "https://files.pythonhosted.org/packages/71/06/0dc56ffc615c8095cd089c9b98ce5c733e990f09ce4e8eea4aaf1041a532/pyzmq-27.0.2-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de84e1694f9507b29e7b263453a2255a73e3d099d258db0f14539bad258abe41", size = 747088, upload-time = "2025-08-21T04:23:05.334Z" }, + { url = "https://files.pythonhosted.org/packages/06/f6/4a50187e023b8848edd3f0a8e197b1a7fb08d261d8c60aae7cb6c3d71612/pyzmq-27.0.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:f0944d65ba2b872b9fcece08411d6347f15a874c775b4c3baae7f278550da0fb", size = 544639, upload-time = "2025-08-21T04:23:07.279Z" }, ] [[package]] name = "questionary" -version = "2.0.1" +version = "2.1.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "prompt-toolkit" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/84/d0/d73525aeba800df7030ac187d09c59dc40df1c878b4fab8669bdc805535d/questionary-2.0.1.tar.gz", hash = "sha256:bcce898bf3dbb446ff62830c86c5c6fb9a22a54146f0f5597d3da43b10d8fc8b", size = 24726 } +sdist = { url = "https://files.pythonhosted.org/packages/f6/45/eafb0bba0f9988f6a2520f9ca2df2c82ddfa8d67c95d6625452e97b204a5/questionary-2.1.1.tar.gz", hash = "sha256:3d7e980292bb0107abaa79c68dd3eee3c561b83a0f89ae482860b181c8bd412d", size = 25845, upload-time = "2025-08-28T19:00:20.851Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0b/e7/2dd8f59d1d328773505f78b85405ddb1cfe74126425d076ce72e65540b8b/questionary-2.0.1-py3-none-any.whl", hash = "sha256:8ab9a01d0b91b68444dff7f6652c1e754105533f083cbe27597c8110ecc230a2", size = 34248 }, + { url = "https://files.pythonhosted.org/packages/3c/26/1062c7ec1b053db9e499b4d2d5bc231743201b74051c973dadeac80a8f43/questionary-2.1.1-py3-none-any.whl", hash = "sha256:a51af13f345f1cdea62347589fbb6df3b290306ab8930713bfae4d475a7d4a59", size = 36753, upload-time = "2025-08-28T19:00:19.56Z" }, ] [[package]] name = "referencing" -version = "0.35.1" +version = "0.36.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "attrs" }, { name = "rpds-py" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/99/5b/73ca1f8e72fff6fa52119dbd185f73a907b1989428917b24cff660129b6d/referencing-0.35.1.tar.gz", hash = "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c", size = 62991 } +sdist = { url = "https://files.pythonhosted.org/packages/2f/db/98b5c277be99dd18bfd91dd04e1b759cad18d1a338188c936e92f921c7e2/referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa", size = 74744, upload-time = "2025-01-25T08:48:16.138Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/59/2056f61236782a2c86b33906c025d4f4a0b17be0161b63b70fd9e8775d36/referencing-0.35.1-py3-none-any.whl", hash = "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de", size = 26684 }, + { url = "https://files.pythonhosted.org/packages/c1/b1/3baf80dc6d2b7bc27a95a67752d0208e410351e3feb4eb78de5f77454d8d/referencing-0.36.2-py3-none-any.whl", hash = "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0", size = 26775, upload-time = "2025-01-25T08:48:14.241Z" }, ] [[package]] name = "requests" -version = "2.32.3" +version = "2.32.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, @@ -2290,9 +2744,9 @@ dependencies = [ { name = "idna" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 } +sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, + { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, ] [[package]] @@ -2302,168 +2756,200 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "six" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/28/ea/a9387748e2d111c3c2b275ba970b735e04e15cdb1eb30693b6b5708c4dbd/rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b", size = 5513 } +sdist = { url = "https://files.pythonhosted.org/packages/28/ea/a9387748e2d111c3c2b275ba970b735e04e15cdb1eb30693b6b5708c4dbd/rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b", size = 5513, upload-time = "2021-05-12T16:37:54.178Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa", size = 3490 }, + { url = "https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa", size = 3490, upload-time = "2021-05-12T16:37:52.536Z" }, ] [[package]] name = "rfc3986-validator" version = "0.1.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/da/88/f270de456dd7d11dcc808abfa291ecdd3f45ff44e3b549ffa01b126464d0/rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055", size = 6760 } +sdist = { url = "https://files.pythonhosted.org/packages/da/88/f270de456dd7d11dcc808abfa291ecdd3f45ff44e3b549ffa01b126464d0/rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055", size = 6760, upload-time = "2019-10-28T16:00:19.144Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9", size = 4242, upload-time = "2019-10-28T16:00:13.976Z" }, +] + +[[package]] +name = "rfc3987-syntax" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "lark" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2c/06/37c1a5557acf449e8e406a830a05bf885ac47d33270aec454ef78675008d/rfc3987_syntax-1.1.0.tar.gz", hash = "sha256:717a62cbf33cffdd16dfa3a497d81ce48a660ea691b1ddd7be710c22f00b4a0d", size = 14239, upload-time = "2025-07-18T01:05:05.015Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9", size = 4242 }, + { url = "https://files.pythonhosted.org/packages/7e/71/44ce230e1b7fadd372515a97e32a83011f906ddded8d03e3c6aafbdedbb7/rfc3987_syntax-1.1.0-py3-none-any.whl", hash = "sha256:6c3d97604e4c5ce9f714898e05401a0445a641cfa276432b0a648c80856f6a3f", size = 8046, upload-time = "2025-07-18T01:05:03.843Z" }, ] [[package]] name = "rich" -version = "13.9.3" +version = "14.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown-it-py" }, { name = "pygments" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d9/e9/cf9ef5245d835065e6673781dbd4b8911d352fb770d56cf0879cf11b7ee1/rich-13.9.3.tar.gz", hash = "sha256:bc1e01b899537598cf02579d2b9f4a415104d3fc439313a7a2c165d76557a08e", size = 222889 } +sdist = { url = "https://files.pythonhosted.org/packages/fe/75/af448d8e52bf1d8fa6a9d089ca6c07ff4453d86c65c145d0a300bb073b9b/rich-14.1.0.tar.gz", hash = "sha256:e497a48b844b0320d45007cdebfeaeed8db2a4f4bcf49f15e455cfc4af11eaa8", size = 224441, upload-time = "2025-07-25T07:32:58.125Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/e2/10e9819cf4a20bd8ea2f5dabafc2e6bf4a78d6a0965daeb60a4b34d1c11f/rich-13.9.3-py3-none-any.whl", hash = "sha256:9836f5096eb2172c9e77df411c1b009bace4193d6a481d534fea75ebba758283", size = 242157 }, + { url = "https://files.pythonhosted.org/packages/e3/30/3c4d035596d3cf444529e0b2953ad0466f6049528a879d27534700580395/rich-14.1.0-py3-none-any.whl", hash = "sha256:536f5f1785986d6dbdea3c75205c473f970777b4a0d6c6dd1b696aa05a3fa04f", size = 243368, upload-time = "2025-07-25T07:32:56.73Z" }, ] [[package]] name = "rpds-py" -version = "0.22.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/01/80/cce854d0921ff2f0a9fa831ba3ad3c65cee3a46711addf39a2af52df2cfd/rpds_py-0.22.3.tar.gz", hash = "sha256:e32fee8ab45d3c2db6da19a5323bc3362237c8b653c70194414b892fd06a080d", size = 26771 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/42/2a/ead1d09e57449b99dcc190d8d2323e3a167421d8f8fdf0f217c6f6befe47/rpds_py-0.22.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:6c7b99ca52c2c1752b544e310101b98a659b720b21db00e65edca34483259967", size = 359514 }, - { url = "https://files.pythonhosted.org/packages/8f/7e/1254f406b7793b586c68e217a6a24ec79040f85e030fff7e9049069284f4/rpds_py-0.22.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:be2eb3f2495ba669d2a985f9b426c1797b7d48d6963899276d22f23e33d47e37", size = 349031 }, - { url = "https://files.pythonhosted.org/packages/aa/da/17c6a2c73730d426df53675ff9cc6653ac7a60b6438d03c18e1c822a576a/rpds_py-0.22.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70eb60b3ae9245ddea20f8a4190bd79c705a22f8028aaf8bbdebe4716c3fab24", size = 381485 }, - { url = "https://files.pythonhosted.org/packages/aa/13/2dbacd820466aa2a3c4b747afb18d71209523d353cf865bf8f4796c969ea/rpds_py-0.22.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4041711832360a9b75cfb11b25a6a97c8fb49c07b8bd43d0d02b45d0b499a4ff", size = 386794 }, - { url = "https://files.pythonhosted.org/packages/6d/62/96905d0a35ad4e4bc3c098b2f34b2e7266e211d08635baa690643d2227be/rpds_py-0.22.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:64607d4cbf1b7e3c3c8a14948b99345eda0e161b852e122c6bb71aab6d1d798c", size = 423523 }, - { url = "https://files.pythonhosted.org/packages/eb/1b/d12770f2b6a9fc2c3ec0d810d7d440f6d465ccd8b7f16ae5385952c28b89/rpds_py-0.22.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e69b0a0e2537f26d73b4e43ad7bc8c8efb39621639b4434b76a3de50c6966e", size = 446695 }, - { url = "https://files.pythonhosted.org/packages/4d/cf/96f1fd75512a017f8e07408b6d5dbeb492d9ed46bfe0555544294f3681b3/rpds_py-0.22.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc27863442d388870c1809a87507727b799c8460573cfbb6dc0eeaef5a11b5ec", size = 381959 }, - { url = "https://files.pythonhosted.org/packages/ab/f0/d1c5b501c8aea85aeb938b555bfdf7612110a2f8cdc21ae0482c93dd0c24/rpds_py-0.22.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e79dd39f1e8c3504be0607e5fc6e86bb60fe3584bec8b782578c3b0fde8d932c", size = 410420 }, - { url = "https://files.pythonhosted.org/packages/33/3b/45b6c58fb6aad5a569ae40fb890fc494c6b02203505a5008ee6dc68e65f7/rpds_py-0.22.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e0fa2d4ec53dc51cf7d3bb22e0aa0143966119f42a0c3e4998293a3dd2856b09", size = 557620 }, - { url = "https://files.pythonhosted.org/packages/83/62/3fdd2d3d47bf0bb9b931c4c73036b4ab3ec77b25e016ae26fab0f02be2af/rpds_py-0.22.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fda7cb070f442bf80b642cd56483b5548e43d366fe3f39b98e67cce780cded00", size = 584202 }, - { url = "https://files.pythonhosted.org/packages/04/f2/5dced98b64874b84ca824292f9cee2e3f30f3bcf231d15a903126684f74d/rpds_py-0.22.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cff63a0272fcd259dcc3be1657b07c929c466b067ceb1c20060e8d10af56f5bf", size = 552787 }, - { url = "https://files.pythonhosted.org/packages/67/13/2273dea1204eda0aea0ef55145da96a9aa28b3f88bb5c70e994f69eda7c3/rpds_py-0.22.3-cp310-cp310-win32.whl", hash = "sha256:9bd7228827ec7bb817089e2eb301d907c0d9827a9e558f22f762bb690b131652", size = 220088 }, - { url = "https://files.pythonhosted.org/packages/4e/80/8c8176b67ad7f4a894967a7a4014ba039626d96f1d4874d53e409b58d69f/rpds_py-0.22.3-cp310-cp310-win_amd64.whl", hash = "sha256:9beeb01d8c190d7581a4d59522cd3d4b6887040dcfc744af99aa59fef3e041a8", size = 231737 }, - { url = "https://files.pythonhosted.org/packages/15/ad/8d1ddf78f2805a71253fcd388017e7b4a0615c22c762b6d35301fef20106/rpds_py-0.22.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d20cfb4e099748ea39e6f7b16c91ab057989712d31761d3300d43134e26e165f", size = 359773 }, - { url = "https://files.pythonhosted.org/packages/c8/75/68c15732293a8485d79fe4ebe9045525502a067865fa4278f178851b2d87/rpds_py-0.22.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:68049202f67380ff9aa52f12e92b1c30115f32e6895cd7198fa2a7961621fc5a", size = 349214 }, - { url = "https://files.pythonhosted.org/packages/3c/4c/7ce50f3070083c2e1b2bbd0fb7046f3da55f510d19e283222f8f33d7d5f4/rpds_py-0.22.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb4f868f712b2dd4bcc538b0a0c1f63a2b1d584c925e69a224d759e7070a12d5", size = 380477 }, - { url = "https://files.pythonhosted.org/packages/9a/e9/835196a69cb229d5c31c13b8ae603bd2da9a6695f35fe4270d398e1db44c/rpds_py-0.22.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bc51abd01f08117283c5ebf64844a35144a0843ff7b2983e0648e4d3d9f10dbb", size = 386171 }, - { url = "https://files.pythonhosted.org/packages/f9/8e/33fc4eba6683db71e91e6d594a2cf3a8fbceb5316629f0477f7ece5e3f75/rpds_py-0.22.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0f3cec041684de9a4684b1572fe28c7267410e02450f4561700ca5a3bc6695a2", size = 422676 }, - { url = "https://files.pythonhosted.org/packages/37/47/2e82d58f8046a98bb9497a8319604c92b827b94d558df30877c4b3c6ccb3/rpds_py-0.22.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7ef9d9da710be50ff6809fed8f1963fecdfecc8b86656cadfca3bc24289414b0", size = 446152 }, - { url = "https://files.pythonhosted.org/packages/e1/78/79c128c3e71abbc8e9739ac27af11dc0f91840a86fce67ff83c65d1ba195/rpds_py-0.22.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59f4a79c19232a5774aee369a0c296712ad0e77f24e62cad53160312b1c1eaa1", size = 381300 }, - { url = "https://files.pythonhosted.org/packages/c9/5b/2e193be0e8b228c1207f31fa3ea79de64dadb4f6a4833111af8145a6bc33/rpds_py-0.22.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a60bce91f81ddaac922a40bbb571a12c1070cb20ebd6d49c48e0b101d87300d", size = 409636 }, - { url = "https://files.pythonhosted.org/packages/c2/3f/687c7100b762d62186a1c1100ffdf99825f6fa5ea94556844bbbd2d0f3a9/rpds_py-0.22.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e89391e6d60251560f0a8f4bd32137b077a80d9b7dbe6d5cab1cd80d2746f648", size = 556708 }, - { url = "https://files.pythonhosted.org/packages/8c/a2/c00cbc4b857e8b3d5e7f7fc4c81e23afd8c138b930f4f3ccf9a41a23e9e4/rpds_py-0.22.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e3fb866d9932a3d7d0c82da76d816996d1667c44891bd861a0f97ba27e84fc74", size = 583554 }, - { url = "https://files.pythonhosted.org/packages/d0/08/696c9872cf56effdad9ed617ac072f6774a898d46b8b8964eab39ec562d2/rpds_py-0.22.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1352ae4f7c717ae8cba93421a63373e582d19d55d2ee2cbb184344c82d2ae55a", size = 552105 }, - { url = "https://files.pythonhosted.org/packages/18/1f/4df560be1e994f5adf56cabd6c117e02de7c88ee238bb4ce03ed50da9d56/rpds_py-0.22.3-cp311-cp311-win32.whl", hash = "sha256:b0b4136a252cadfa1adb705bb81524eee47d9f6aab4f2ee4fa1e9d3cd4581f64", size = 220199 }, - { url = "https://files.pythonhosted.org/packages/b8/1b/c29b570bc5db8237553002788dc734d6bd71443a2ceac2a58202ec06ef12/rpds_py-0.22.3-cp311-cp311-win_amd64.whl", hash = "sha256:8bd7c8cfc0b8247c8799080fbff54e0b9619e17cdfeb0478ba7295d43f635d7c", size = 231775 }, - { url = "https://files.pythonhosted.org/packages/75/47/3383ee3bd787a2a5e65a9b9edc37ccf8505c0a00170e3a5e6ea5fbcd97f7/rpds_py-0.22.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:27e98004595899949bd7a7b34e91fa7c44d7a97c40fcaf1d874168bb652ec67e", size = 352334 }, - { url = "https://files.pythonhosted.org/packages/40/14/aa6400fa8158b90a5a250a77f2077c0d0cd8a76fce31d9f2b289f04c6dec/rpds_py-0.22.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1978d0021e943aae58b9b0b196fb4895a25cc53d3956b8e35e0b7682eefb6d56", size = 342111 }, - { url = "https://files.pythonhosted.org/packages/7d/06/395a13bfaa8a28b302fb433fb285a67ce0ea2004959a027aea8f9c52bad4/rpds_py-0.22.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:655ca44a831ecb238d124e0402d98f6212ac527a0ba6c55ca26f616604e60a45", size = 384286 }, - { url = "https://files.pythonhosted.org/packages/43/52/d8eeaffab047e6b7b7ef7f00d5ead074a07973968ffa2d5820fa131d7852/rpds_py-0.22.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:feea821ee2a9273771bae61194004ee2fc33f8ec7db08117ef9147d4bbcbca8e", size = 391739 }, - { url = "https://files.pythonhosted.org/packages/83/31/52dc4bde85c60b63719610ed6f6d61877effdb5113a72007679b786377b8/rpds_py-0.22.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:22bebe05a9ffc70ebfa127efbc429bc26ec9e9b4ee4d15a740033efda515cf3d", size = 427306 }, - { url = "https://files.pythonhosted.org/packages/70/d5/1bab8e389c2261dba1764e9e793ed6830a63f830fdbec581a242c7c46bda/rpds_py-0.22.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3af6e48651c4e0d2d166dc1b033b7042ea3f871504b6805ba5f4fe31581d8d38", size = 442717 }, - { url = "https://files.pythonhosted.org/packages/82/a1/a45f3e30835b553379b3a56ea6c4eb622cf11e72008229af840e4596a8ea/rpds_py-0.22.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67ba3c290821343c192f7eae1d8fd5999ca2dc99994114643e2f2d3e6138b15", size = 385721 }, - { url = "https://files.pythonhosted.org/packages/a6/27/780c942de3120bdd4d0e69583f9c96e179dfff082f6ecbb46b8d6488841f/rpds_py-0.22.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:02fbb9c288ae08bcb34fb41d516d5eeb0455ac35b5512d03181d755d80810059", size = 415824 }, - { url = "https://files.pythonhosted.org/packages/94/0b/aa0542ca88ad20ea719b06520f925bae348ea5c1fdf201b7e7202d20871d/rpds_py-0.22.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f56a6b404f74ab372da986d240e2e002769a7d7102cc73eb238a4f72eec5284e", size = 561227 }, - { url = "https://files.pythonhosted.org/packages/0d/92/3ed77d215f82c8f844d7f98929d56cc321bb0bcfaf8f166559b8ec56e5f1/rpds_py-0.22.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0a0461200769ab3b9ab7e513f6013b7a97fdeee41c29b9db343f3c5a8e2b9e61", size = 587424 }, - { url = "https://files.pythonhosted.org/packages/09/42/cacaeb047a22cab6241f107644f230e2935d4efecf6488859a7dd82fc47d/rpds_py-0.22.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8633e471c6207a039eff6aa116e35f69f3156b3989ea3e2d755f7bc41754a4a7", size = 555953 }, - { url = "https://files.pythonhosted.org/packages/e6/52/c921dc6d5f5d45b212a456c1f5b17df1a471127e8037eb0972379e39dff4/rpds_py-0.22.3-cp312-cp312-win32.whl", hash = "sha256:593eba61ba0c3baae5bc9be2f5232430453fb4432048de28399ca7376de9c627", size = 221339 }, - { url = "https://files.pythonhosted.org/packages/f2/c7/f82b5be1e8456600395366f86104d1bd8d0faed3802ad511ef6d60c30d98/rpds_py-0.22.3-cp312-cp312-win_amd64.whl", hash = "sha256:d115bffdd417c6d806ea9069237a4ae02f513b778e3789a359bc5856e0404cc4", size = 235786 }, - { url = "https://files.pythonhosted.org/packages/8b/63/e29f8ee14fcf383574f73b6bbdcbec0fbc2e5fc36b4de44d1ac389b1de62/rpds_py-0.22.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:d48424e39c2611ee1b84ad0f44fb3b2b53d473e65de061e3f460fc0be5f1939d", size = 360786 }, - { url = "https://files.pythonhosted.org/packages/d3/e0/771ee28b02a24e81c8c0e645796a371350a2bb6672753144f36ae2d2afc9/rpds_py-0.22.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:24e8abb5878e250f2eb0d7859a8e561846f98910326d06c0d51381fed59357bd", size = 350589 }, - { url = "https://files.pythonhosted.org/packages/cf/49/abad4c4a1e6f3adf04785a99c247bfabe55ed868133e2d1881200aa5d381/rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b232061ca880db21fa14defe219840ad9b74b6158adb52ddf0e87bead9e8493", size = 381848 }, - { url = "https://files.pythonhosted.org/packages/3a/7d/f4bc6d6fbe6af7a0d2b5f2ee77079efef7c8528712745659ec0026888998/rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac0a03221cdb5058ce0167ecc92a8c89e8d0decdc9e99a2ec23380793c4dcb96", size = 387879 }, - { url = "https://files.pythonhosted.org/packages/13/b0/575c797377fdcd26cedbb00a3324232e4cb2c5d121f6e4b0dbf8468b12ef/rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb0c341fa71df5a4595f9501df4ac5abfb5a09580081dffbd1ddd4654e6e9123", size = 423916 }, - { url = "https://files.pythonhosted.org/packages/54/78/87157fa39d58f32a68d3326f8a81ad8fb99f49fe2aa7ad9a1b7d544f9478/rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf9db5488121b596dbfc6718c76092fda77b703c1f7533a226a5a9f65248f8ad", size = 448410 }, - { url = "https://files.pythonhosted.org/packages/59/69/860f89996065a88be1b6ff2d60e96a02b920a262d8aadab99e7903986597/rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b8db6b5b2d4491ad5b6bdc2bc7c017eec108acbf4e6785f42a9eb0ba234f4c9", size = 382841 }, - { url = "https://files.pythonhosted.org/packages/bd/d7/bc144e10d27e3cb350f98df2492a319edd3caaf52ddfe1293f37a9afbfd7/rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b3d504047aba448d70cf6fa22e06cb09f7cbd761939fdd47604f5e007675c24e", size = 409662 }, - { url = "https://files.pythonhosted.org/packages/14/2a/6bed0b05233c291a94c7e89bc76ffa1c619d4e1979fbfe5d96024020c1fb/rpds_py-0.22.3-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:e61b02c3f7a1e0b75e20c3978f7135fd13cb6cf551bf4a6d29b999a88830a338", size = 558221 }, - { url = "https://files.pythonhosted.org/packages/11/23/cd8f566de444a137bc1ee5795e47069a947e60810ba4152886fe5308e1b7/rpds_py-0.22.3-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:e35ba67d65d49080e8e5a1dd40101fccdd9798adb9b050ff670b7d74fa41c566", size = 583780 }, - { url = "https://files.pythonhosted.org/packages/8d/63/79c3602afd14d501f751e615a74a59040328da5ef29ed5754ae80d236b84/rpds_py-0.22.3-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:26fd7cac7dd51011a245f29a2cc6489c4608b5a8ce8d75661bb4a1066c52dfbe", size = 553619 }, - { url = "https://files.pythonhosted.org/packages/9f/2e/c5c1689e80298d4e94c75b70faada4c25445739d91b94c211244a3ed7ed1/rpds_py-0.22.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:177c7c0fce2855833819c98e43c262007f42ce86651ffbb84f37883308cb0e7d", size = 233338 }, +version = "0.27.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e9/dd/2c0cbe774744272b0ae725f44032c77bdcab6e8bcf544bffa3b6e70c8dba/rpds_py-0.27.1.tar.gz", hash = "sha256:26a1c73171d10b7acccbded82bf6a586ab8203601e565badc74bbbf8bc5a10f8", size = 27479, upload-time = "2025-08-27T12:16:36.024Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b5/c1/7907329fbef97cbd49db6f7303893bd1dd5a4a3eae415839ffdfb0762cae/rpds_py-0.27.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:be898f271f851f68b318872ce6ebebbc62f303b654e43bf72683dbdc25b7c881", size = 371063, upload-time = "2025-08-27T12:12:47.856Z" }, + { url = "https://files.pythonhosted.org/packages/11/94/2aab4bc86228bcf7c48760990273653a4900de89c7537ffe1b0d6097ed39/rpds_py-0.27.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:62ac3d4e3e07b58ee0ddecd71d6ce3b1637de2d373501412df395a0ec5f9beb5", size = 353210, upload-time = "2025-08-27T12:12:49.187Z" }, + { url = "https://files.pythonhosted.org/packages/3a/57/f5eb3ecf434342f4f1a46009530e93fd201a0b5b83379034ebdb1d7c1a58/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4708c5c0ceb2d034f9991623631d3d23cb16e65c83736ea020cdbe28d57c0a0e", size = 381636, upload-time = "2025-08-27T12:12:50.492Z" }, + { url = "https://files.pythonhosted.org/packages/ae/f4/ef95c5945e2ceb5119571b184dd5a1cc4b8541bbdf67461998cfeac9cb1e/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:abfa1171a9952d2e0002aba2ad3780820b00cc3d9c98c6630f2e93271501f66c", size = 394341, upload-time = "2025-08-27T12:12:52.024Z" }, + { url = "https://files.pythonhosted.org/packages/5a/7e/4bd610754bf492d398b61725eb9598ddd5eb86b07d7d9483dbcd810e20bc/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b507d19f817ebaca79574b16eb2ae412e5c0835542c93fe9983f1e432aca195", size = 523428, upload-time = "2025-08-27T12:12:53.779Z" }, + { url = "https://files.pythonhosted.org/packages/9f/e5/059b9f65a8c9149361a8b75094864ab83b94718344db511fd6117936ed2a/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:168b025f8fd8d8d10957405f3fdcef3dc20f5982d398f90851f4abc58c566c52", size = 402923, upload-time = "2025-08-27T12:12:55.15Z" }, + { url = "https://files.pythonhosted.org/packages/f5/48/64cabb7daced2968dd08e8a1b7988bf358d7bd5bcd5dc89a652f4668543c/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb56c6210ef77caa58e16e8c17d35c63fe3f5b60fd9ba9d424470c3400bcf9ed", size = 384094, upload-time = "2025-08-27T12:12:57.194Z" }, + { url = "https://files.pythonhosted.org/packages/ae/e1/dc9094d6ff566bff87add8a510c89b9e158ad2ecd97ee26e677da29a9e1b/rpds_py-0.27.1-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:d252f2d8ca0195faa707f8eb9368955760880b2b42a8ee16d382bf5dd807f89a", size = 401093, upload-time = "2025-08-27T12:12:58.985Z" }, + { url = "https://files.pythonhosted.org/packages/37/8e/ac8577e3ecdd5593e283d46907d7011618994e1d7ab992711ae0f78b9937/rpds_py-0.27.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6e5e54da1e74b91dbc7996b56640f79b195d5925c2b78efaa8c5d53e1d88edde", size = 417969, upload-time = "2025-08-27T12:13:00.367Z" }, + { url = "https://files.pythonhosted.org/packages/66/6d/87507430a8f74a93556fe55c6485ba9c259949a853ce407b1e23fea5ba31/rpds_py-0.27.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ffce0481cc6e95e5b3f0a47ee17ffbd234399e6d532f394c8dce320c3b089c21", size = 558302, upload-time = "2025-08-27T12:13:01.737Z" }, + { url = "https://files.pythonhosted.org/packages/3a/bb/1db4781ce1dda3eecc735e3152659a27b90a02ca62bfeea17aee45cc0fbc/rpds_py-0.27.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a205fdfe55c90c2cd8e540ca9ceba65cbe6629b443bc05db1f590a3db8189ff9", size = 589259, upload-time = "2025-08-27T12:13:03.127Z" }, + { url = "https://files.pythonhosted.org/packages/7b/0e/ae1c8943d11a814d01b482e1f8da903f88047a962dff9bbdadf3bd6e6fd1/rpds_py-0.27.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:689fb5200a749db0415b092972e8eba85847c23885c8543a8b0f5c009b1a5948", size = 554983, upload-time = "2025-08-27T12:13:04.516Z" }, + { url = "https://files.pythonhosted.org/packages/b2/d5/0b2a55415931db4f112bdab072443ff76131b5ac4f4dc98d10d2d357eb03/rpds_py-0.27.1-cp311-cp311-win32.whl", hash = "sha256:3182af66048c00a075010bc7f4860f33913528a4b6fc09094a6e7598e462fe39", size = 217154, upload-time = "2025-08-27T12:13:06.278Z" }, + { url = "https://files.pythonhosted.org/packages/24/75/3b7ffe0d50dc86a6a964af0d1cc3a4a2cdf437cb7b099a4747bbb96d1819/rpds_py-0.27.1-cp311-cp311-win_amd64.whl", hash = "sha256:b4938466c6b257b2f5c4ff98acd8128ec36b5059e5c8f8372d79316b1c36bb15", size = 228627, upload-time = "2025-08-27T12:13:07.625Z" }, + { url = "https://files.pythonhosted.org/packages/8d/3f/4fd04c32abc02c710f09a72a30c9a55ea3cc154ef8099078fd50a0596f8e/rpds_py-0.27.1-cp311-cp311-win_arm64.whl", hash = "sha256:2f57af9b4d0793e53266ee4325535a31ba48e2f875da81a9177c9926dfa60746", size = 220998, upload-time = "2025-08-27T12:13:08.972Z" }, + { url = "https://files.pythonhosted.org/packages/bd/fe/38de28dee5df58b8198c743fe2bea0c785c6d40941b9950bac4cdb71a014/rpds_py-0.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ae2775c1973e3c30316892737b91f9283f9908e3cc7625b9331271eaaed7dc90", size = 361887, upload-time = "2025-08-27T12:13:10.233Z" }, + { url = "https://files.pythonhosted.org/packages/7c/9a/4b6c7eedc7dd90986bf0fab6ea2a091ec11c01b15f8ba0a14d3f80450468/rpds_py-0.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2643400120f55c8a96f7c9d858f7be0c88d383cd4653ae2cf0d0c88f668073e5", size = 345795, upload-time = "2025-08-27T12:13:11.65Z" }, + { url = "https://files.pythonhosted.org/packages/6f/0e/e650e1b81922847a09cca820237b0edee69416a01268b7754d506ade11ad/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16323f674c089b0360674a4abd28d5042947d54ba620f72514d69be4ff64845e", size = 385121, upload-time = "2025-08-27T12:13:13.008Z" }, + { url = "https://files.pythonhosted.org/packages/1b/ea/b306067a712988e2bff00dcc7c8f31d26c29b6d5931b461aa4b60a013e33/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9a1f4814b65eacac94a00fc9a526e3fdafd78e439469644032032d0d63de4881", size = 398976, upload-time = "2025-08-27T12:13:14.368Z" }, + { url = "https://files.pythonhosted.org/packages/2c/0a/26dc43c8840cb8fe239fe12dbc8d8de40f2365e838f3d395835dde72f0e5/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ba32c16b064267b22f1850a34051121d423b6f7338a12b9459550eb2096e7ec", size = 525953, upload-time = "2025-08-27T12:13:15.774Z" }, + { url = "https://files.pythonhosted.org/packages/22/14/c85e8127b573aaf3a0cbd7fbb8c9c99e735a4a02180c84da2a463b766e9e/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5c20f33fd10485b80f65e800bbe5f6785af510b9f4056c5a3c612ebc83ba6cb", size = 407915, upload-time = "2025-08-27T12:13:17.379Z" }, + { url = "https://files.pythonhosted.org/packages/ed/7b/8f4fee9ba1fb5ec856eb22d725a4efa3deb47f769597c809e03578b0f9d9/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:466bfe65bd932da36ff279ddd92de56b042f2266d752719beb97b08526268ec5", size = 386883, upload-time = "2025-08-27T12:13:18.704Z" }, + { url = "https://files.pythonhosted.org/packages/86/47/28fa6d60f8b74fcdceba81b272f8d9836ac0340570f68f5df6b41838547b/rpds_py-0.27.1-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:41e532bbdcb57c92ba3be62c42e9f096431b4cf478da9bc3bc6ce5c38ab7ba7a", size = 405699, upload-time = "2025-08-27T12:13:20.089Z" }, + { url = "https://files.pythonhosted.org/packages/d0/fd/c5987b5e054548df56953a21fe2ebed51fc1ec7c8f24fd41c067b68c4a0a/rpds_py-0.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f149826d742b406579466283769a8ea448eed82a789af0ed17b0cd5770433444", size = 423713, upload-time = "2025-08-27T12:13:21.436Z" }, + { url = "https://files.pythonhosted.org/packages/ac/ba/3c4978b54a73ed19a7d74531be37a8bcc542d917c770e14d372b8daea186/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:80c60cfb5310677bd67cb1e85a1e8eb52e12529545441b43e6f14d90b878775a", size = 562324, upload-time = "2025-08-27T12:13:22.789Z" }, + { url = "https://files.pythonhosted.org/packages/b5/6c/6943a91768fec16db09a42b08644b960cff540c66aab89b74be6d4a144ba/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7ee6521b9baf06085f62ba9c7a3e5becffbc32480d2f1b351559c001c38ce4c1", size = 593646, upload-time = "2025-08-27T12:13:24.122Z" }, + { url = "https://files.pythonhosted.org/packages/11/73/9d7a8f4be5f4396f011a6bb7a19fe26303a0dac9064462f5651ced2f572f/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a512c8263249a9d68cac08b05dd59d2b3f2061d99b322813cbcc14c3c7421998", size = 558137, upload-time = "2025-08-27T12:13:25.557Z" }, + { url = "https://files.pythonhosted.org/packages/6e/96/6772cbfa0e2485bcceef8071de7821f81aeac8bb45fbfd5542a3e8108165/rpds_py-0.27.1-cp312-cp312-win32.whl", hash = "sha256:819064fa048ba01b6dadc5116f3ac48610435ac9a0058bbde98e569f9e785c39", size = 221343, upload-time = "2025-08-27T12:13:26.967Z" }, + { url = "https://files.pythonhosted.org/packages/67/b6/c82f0faa9af1c6a64669f73a17ee0eeef25aff30bb9a1c318509efe45d84/rpds_py-0.27.1-cp312-cp312-win_amd64.whl", hash = "sha256:d9199717881f13c32c4046a15f024971a3b78ad4ea029e8da6b86e5aa9cf4594", size = 232497, upload-time = "2025-08-27T12:13:28.326Z" }, + { url = "https://files.pythonhosted.org/packages/e1/96/2817b44bd2ed11aebacc9251da03689d56109b9aba5e311297b6902136e2/rpds_py-0.27.1-cp312-cp312-win_arm64.whl", hash = "sha256:33aa65b97826a0e885ef6e278fbd934e98cdcfed80b63946025f01e2f5b29502", size = 222790, upload-time = "2025-08-27T12:13:29.71Z" }, + { url = "https://files.pythonhosted.org/packages/cc/77/610aeee8d41e39080c7e14afa5387138e3c9fa9756ab893d09d99e7d8e98/rpds_py-0.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:e4b9fcfbc021633863a37e92571d6f91851fa656f0180246e84cbd8b3f6b329b", size = 361741, upload-time = "2025-08-27T12:13:31.039Z" }, + { url = "https://files.pythonhosted.org/packages/3a/fc/c43765f201c6a1c60be2043cbdb664013def52460a4c7adace89d6682bf4/rpds_py-0.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1441811a96eadca93c517d08df75de45e5ffe68aa3089924f963c782c4b898cf", size = 345574, upload-time = "2025-08-27T12:13:32.902Z" }, + { url = "https://files.pythonhosted.org/packages/20/42/ee2b2ca114294cd9847d0ef9c26d2b0851b2e7e00bf14cc4c0b581df0fc3/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55266dafa22e672f5a4f65019015f90336ed31c6383bd53f5e7826d21a0e0b83", size = 385051, upload-time = "2025-08-27T12:13:34.228Z" }, + { url = "https://files.pythonhosted.org/packages/fd/e8/1e430fe311e4799e02e2d1af7c765f024e95e17d651612425b226705f910/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d78827d7ac08627ea2c8e02c9e5b41180ea5ea1f747e9db0915e3adf36b62dcf", size = 398395, upload-time = "2025-08-27T12:13:36.132Z" }, + { url = "https://files.pythonhosted.org/packages/82/95/9dc227d441ff2670651c27a739acb2535ccaf8b351a88d78c088965e5996/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae92443798a40a92dc5f0b01d8a7c93adde0c4dc965310a29ae7c64d72b9fad2", size = 524334, upload-time = "2025-08-27T12:13:37.562Z" }, + { url = "https://files.pythonhosted.org/packages/87/01/a670c232f401d9ad461d9a332aa4080cd3cb1d1df18213dbd0d2a6a7ab51/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c46c9dd2403b66a2a3b9720ec4b74d4ab49d4fabf9f03dfdce2d42af913fe8d0", size = 407691, upload-time = "2025-08-27T12:13:38.94Z" }, + { url = "https://files.pythonhosted.org/packages/03/36/0a14aebbaa26fe7fab4780c76f2239e76cc95a0090bdb25e31d95c492fcd/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2efe4eb1d01b7f5f1939f4ef30ecea6c6b3521eec451fb93191bf84b2a522418", size = 386868, upload-time = "2025-08-27T12:13:40.192Z" }, + { url = "https://files.pythonhosted.org/packages/3b/03/8c897fb8b5347ff6c1cc31239b9611c5bf79d78c984430887a353e1409a1/rpds_py-0.27.1-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:15d3b4d83582d10c601f481eca29c3f138d44c92187d197aff663a269197c02d", size = 405469, upload-time = "2025-08-27T12:13:41.496Z" }, + { url = "https://files.pythonhosted.org/packages/da/07/88c60edc2df74850d496d78a1fdcdc7b54360a7f610a4d50008309d41b94/rpds_py-0.27.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4ed2e16abbc982a169d30d1a420274a709949e2cbdef119fe2ec9d870b42f274", size = 422125, upload-time = "2025-08-27T12:13:42.802Z" }, + { url = "https://files.pythonhosted.org/packages/6b/86/5f4c707603e41b05f191a749984f390dabcbc467cf833769b47bf14ba04f/rpds_py-0.27.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a75f305c9b013289121ec0f1181931975df78738cdf650093e6b86d74aa7d8dd", size = 562341, upload-time = "2025-08-27T12:13:44.472Z" }, + { url = "https://files.pythonhosted.org/packages/b2/92/3c0cb2492094e3cd9baf9e49bbb7befeceb584ea0c1a8b5939dca4da12e5/rpds_py-0.27.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:67ce7620704745881a3d4b0ada80ab4d99df390838839921f99e63c474f82cf2", size = 592511, upload-time = "2025-08-27T12:13:45.898Z" }, + { url = "https://files.pythonhosted.org/packages/10/bb/82e64fbb0047c46a168faa28d0d45a7851cd0582f850b966811d30f67ad8/rpds_py-0.27.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9d992ac10eb86d9b6f369647b6a3f412fc0075cfd5d799530e84d335e440a002", size = 557736, upload-time = "2025-08-27T12:13:47.408Z" }, + { url = "https://files.pythonhosted.org/packages/00/95/3c863973d409210da7fb41958172c6b7dbe7fc34e04d3cc1f10bb85e979f/rpds_py-0.27.1-cp313-cp313-win32.whl", hash = "sha256:4f75e4bd8ab8db624e02c8e2fc4063021b58becdbe6df793a8111d9343aec1e3", size = 221462, upload-time = "2025-08-27T12:13:48.742Z" }, + { url = "https://files.pythonhosted.org/packages/ce/2c/5867b14a81dc217b56d95a9f2a40fdbc56a1ab0181b80132beeecbd4b2d6/rpds_py-0.27.1-cp313-cp313-win_amd64.whl", hash = "sha256:f9025faafc62ed0b75a53e541895ca272815bec18abe2249ff6501c8f2e12b83", size = 232034, upload-time = "2025-08-27T12:13:50.11Z" }, + { url = "https://files.pythonhosted.org/packages/c7/78/3958f3f018c01923823f1e47f1cc338e398814b92d83cd278364446fac66/rpds_py-0.27.1-cp313-cp313-win_arm64.whl", hash = "sha256:ed10dc32829e7d222b7d3b93136d25a406ba9788f6a7ebf6809092da1f4d279d", size = 222392, upload-time = "2025-08-27T12:13:52.587Z" }, + { url = "https://files.pythonhosted.org/packages/01/76/1cdf1f91aed5c3a7bf2eba1f1c4e4d6f57832d73003919a20118870ea659/rpds_py-0.27.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:92022bbbad0d4426e616815b16bc4127f83c9a74940e1ccf3cfe0b387aba0228", size = 358355, upload-time = "2025-08-27T12:13:54.012Z" }, + { url = "https://files.pythonhosted.org/packages/c3/6f/bf142541229374287604caf3bb2a4ae17f0a580798fd72d3b009b532db4e/rpds_py-0.27.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:47162fdab9407ec3f160805ac3e154df042e577dd53341745fc7fb3f625e6d92", size = 342138, upload-time = "2025-08-27T12:13:55.791Z" }, + { url = "https://files.pythonhosted.org/packages/1a/77/355b1c041d6be40886c44ff5e798b4e2769e497b790f0f7fd1e78d17e9a8/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb89bec23fddc489e5d78b550a7b773557c9ab58b7946154a10a6f7a214a48b2", size = 380247, upload-time = "2025-08-27T12:13:57.683Z" }, + { url = "https://files.pythonhosted.org/packages/d6/a4/d9cef5c3946ea271ce2243c51481971cd6e34f21925af2783dd17b26e815/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e48af21883ded2b3e9eb48cb7880ad8598b31ab752ff3be6457001d78f416723", size = 390699, upload-time = "2025-08-27T12:13:59.137Z" }, + { url = "https://files.pythonhosted.org/packages/3a/06/005106a7b8c6c1a7e91b73169e49870f4af5256119d34a361ae5240a0c1d/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6f5b7bd8e219ed50299e58551a410b64daafb5017d54bbe822e003856f06a802", size = 521852, upload-time = "2025-08-27T12:14:00.583Z" }, + { url = "https://files.pythonhosted.org/packages/e5/3e/50fb1dac0948e17a02eb05c24510a8fe12d5ce8561c6b7b7d1339ab7ab9c/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08f1e20bccf73b08d12d804d6e1c22ca5530e71659e6673bce31a6bb71c1e73f", size = 402582, upload-time = "2025-08-27T12:14:02.034Z" }, + { url = "https://files.pythonhosted.org/packages/cb/b0/f4e224090dc5b0ec15f31a02d746ab24101dd430847c4d99123798661bfc/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dc5dceeaefcc96dc192e3a80bbe1d6c410c469e97bdd47494a7d930987f18b2", size = 384126, upload-time = "2025-08-27T12:14:03.437Z" }, + { url = "https://files.pythonhosted.org/packages/54/77/ac339d5f82b6afff1df8f0fe0d2145cc827992cb5f8eeb90fc9f31ef7a63/rpds_py-0.27.1-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:d76f9cc8665acdc0c9177043746775aa7babbf479b5520b78ae4002d889f5c21", size = 399486, upload-time = "2025-08-27T12:14:05.443Z" }, + { url = "https://files.pythonhosted.org/packages/d6/29/3e1c255eee6ac358c056a57d6d6869baa00a62fa32eea5ee0632039c50a3/rpds_py-0.27.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:134fae0e36022edad8290a6661edf40c023562964efea0cc0ec7f5d392d2aaef", size = 414832, upload-time = "2025-08-27T12:14:06.902Z" }, + { url = "https://files.pythonhosted.org/packages/3f/db/6d498b844342deb3fa1d030598db93937a9964fcf5cb4da4feb5f17be34b/rpds_py-0.27.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:eb11a4f1b2b63337cfd3b4d110af778a59aae51c81d195768e353d8b52f88081", size = 557249, upload-time = "2025-08-27T12:14:08.37Z" }, + { url = "https://files.pythonhosted.org/packages/60/f3/690dd38e2310b6f68858a331399b4d6dbb9132c3e8ef8b4333b96caf403d/rpds_py-0.27.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:13e608ac9f50a0ed4faec0e90ece76ae33b34c0e8656e3dceb9a7db994c692cd", size = 587356, upload-time = "2025-08-27T12:14:10.034Z" }, + { url = "https://files.pythonhosted.org/packages/86/e3/84507781cccd0145f35b1dc32c72675200c5ce8d5b30f813e49424ef68fc/rpds_py-0.27.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dd2135527aa40f061350c3f8f89da2644de26cd73e4de458e79606384f4f68e7", size = 555300, upload-time = "2025-08-27T12:14:11.783Z" }, + { url = "https://files.pythonhosted.org/packages/e5/ee/375469849e6b429b3516206b4580a79e9ef3eb12920ddbd4492b56eaacbe/rpds_py-0.27.1-cp313-cp313t-win32.whl", hash = "sha256:3020724ade63fe320a972e2ffd93b5623227e684315adce194941167fee02688", size = 216714, upload-time = "2025-08-27T12:14:13.629Z" }, + { url = "https://files.pythonhosted.org/packages/21/87/3fc94e47c9bd0742660e84706c311a860dcae4374cf4a03c477e23ce605a/rpds_py-0.27.1-cp313-cp313t-win_amd64.whl", hash = "sha256:8ee50c3e41739886606388ba3ab3ee2aae9f35fb23f833091833255a31740797", size = 228943, upload-time = "2025-08-27T12:14:14.937Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ed/e1fba02de17f4f76318b834425257c8ea297e415e12c68b4361f63e8ae92/rpds_py-0.27.1-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cdfe4bb2f9fe7458b7453ad3c33e726d6d1c7c0a72960bcc23800d77384e42df", size = 371402, upload-time = "2025-08-27T12:15:51.561Z" }, + { url = "https://files.pythonhosted.org/packages/af/7c/e16b959b316048b55585a697e94add55a4ae0d984434d279ea83442e460d/rpds_py-0.27.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:8fabb8fd848a5f75a2324e4a84501ee3a5e3c78d8603f83475441866e60b94a3", size = 354084, upload-time = "2025-08-27T12:15:53.219Z" }, + { url = "https://files.pythonhosted.org/packages/de/c1/ade645f55de76799fdd08682d51ae6724cb46f318573f18be49b1e040428/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eda8719d598f2f7f3e0f885cba8646644b55a187762bec091fa14a2b819746a9", size = 383090, upload-time = "2025-08-27T12:15:55.158Z" }, + { url = "https://files.pythonhosted.org/packages/1f/27/89070ca9b856e52960da1472efcb6c20ba27cfe902f4f23ed095b9cfc61d/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3c64d07e95606ec402a0a1c511fe003873fa6af630bda59bac77fac8b4318ebc", size = 394519, upload-time = "2025-08-27T12:15:57.238Z" }, + { url = "https://files.pythonhosted.org/packages/b3/28/be120586874ef906aa5aeeae95ae8df4184bc757e5b6bd1c729ccff45ed5/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:93a2ed40de81bcff59aabebb626562d48332f3d028ca2036f1d23cbb52750be4", size = 523817, upload-time = "2025-08-27T12:15:59.237Z" }, + { url = "https://files.pythonhosted.org/packages/a8/ef/70cc197bc11cfcde02a86f36ac1eed15c56667c2ebddbdb76a47e90306da/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:387ce8c44ae94e0ec50532d9cb0edce17311024c9794eb196b90e1058aadeb66", size = 403240, upload-time = "2025-08-27T12:16:00.923Z" }, + { url = "https://files.pythonhosted.org/packages/cf/35/46936cca449f7f518f2f4996e0e8344db4b57e2081e752441154089d2a5f/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aaf94f812c95b5e60ebaf8bfb1898a7d7cb9c1af5744d4a67fa47796e0465d4e", size = 385194, upload-time = "2025-08-27T12:16:02.802Z" }, + { url = "https://files.pythonhosted.org/packages/e1/62/29c0d3e5125c3270b51415af7cbff1ec587379c84f55a5761cc9efa8cd06/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:4848ca84d6ded9b58e474dfdbad4b8bfb450344c0551ddc8d958bf4b36aa837c", size = 402086, upload-time = "2025-08-27T12:16:04.806Z" }, + { url = "https://files.pythonhosted.org/packages/8f/66/03e1087679227785474466fdd04157fb793b3b76e3fcf01cbf4c693c1949/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2bde09cbcf2248b73c7c323be49b280180ff39fadcfe04e7b6f54a678d02a7cf", size = 419272, upload-time = "2025-08-27T12:16:06.471Z" }, + { url = "https://files.pythonhosted.org/packages/6a/24/e3e72d265121e00b063aef3e3501e5b2473cf1b23511d56e529531acf01e/rpds_py-0.27.1-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:94c44ee01fd21c9058f124d2d4f0c9dc7634bec93cd4b38eefc385dabe71acbf", size = 560003, upload-time = "2025-08-27T12:16:08.06Z" }, + { url = "https://files.pythonhosted.org/packages/26/ca/f5a344c534214cc2d41118c0699fffbdc2c1bc7046f2a2b9609765ab9c92/rpds_py-0.27.1-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:df8b74962e35c9249425d90144e721eed198e6555a0e22a563d29fe4486b51f6", size = 590482, upload-time = "2025-08-27T12:16:10.137Z" }, + { url = "https://files.pythonhosted.org/packages/ce/08/4349bdd5c64d9d193c360aa9db89adeee6f6682ab8825dca0a3f535f434f/rpds_py-0.27.1-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:dc23e6820e3b40847e2f4a7726462ba0cf53089512abe9ee16318c366494c17a", size = 556523, upload-time = "2025-08-27T12:16:12.188Z" }, ] [[package]] name = "ruamel-yaml" -version = "0.18.6" +version = "0.18.15" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "ruamel-yaml-clib", marker = "platform_python_implementation == 'CPython'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/29/81/4dfc17eb6ebb1aac314a3eb863c1325b907863a1b8b1382cdffcb6ac0ed9/ruamel.yaml-0.18.6.tar.gz", hash = "sha256:8b27e6a217e786c6fbe5634d8f3f11bc63e0f80f6a5890f28863d9c45aac311b", size = 143362 } +sdist = { url = "https://files.pythonhosted.org/packages/3e/db/f3950f5e5031b618aae9f423a39bf81a55c148aecd15a34527898e752cf4/ruamel.yaml-0.18.15.tar.gz", hash = "sha256:dbfca74b018c4c3fba0b9cc9ee33e53c371194a9000e694995e620490fd40700", size = 146865, upload-time = "2025-08-19T11:15:10.694Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/73/67/8ece580cc363331d9a53055130f86b096bf16e38156e33b1d3014fffda6b/ruamel.yaml-0.18.6-py3-none-any.whl", hash = "sha256:57b53ba33def16c4f3d807c0ccbc00f8a6081827e81ba2491691b76882d0c636", size = 117761 }, + { url = "https://files.pythonhosted.org/packages/d1/e5/f2a0621f1781b76a38194acae72f01e37b1941470407345b6e8653ad7640/ruamel.yaml-0.18.15-py3-none-any.whl", hash = "sha256:148f6488d698b7a5eded5ea793a025308b25eca97208181b6a026037f391f701", size = 119702, upload-time = "2025-08-19T11:15:07.696Z" }, ] [[package]] name = "ruamel-yaml-clib" version = "0.2.12" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/20/84/80203abff8ea4993a87d823a5f632e4d92831ef75d404c9fc78d0176d2b5/ruamel.yaml.clib-0.2.12.tar.gz", hash = "sha256:6c8fbb13ec503f99a91901ab46e0b07ae7941cd527393187039aec586fdfd36f", size = 225315 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/70/57/40a958e863e299f0c74ef32a3bde9f2d1ea8d69669368c0c502a0997f57f/ruamel.yaml.clib-0.2.12-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:11f891336688faf5156a36293a9c362bdc7c88f03a8a027c2c1d8e0bcde998e5", size = 131301 }, - { url = "https://files.pythonhosted.org/packages/98/a8/29a3eb437b12b95f50a6bcc3d7d7214301c6c529d8fdc227247fa84162b5/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:a606ef75a60ecf3d924613892cc603b154178ee25abb3055db5062da811fd969", size = 633728 }, - { url = "https://files.pythonhosted.org/packages/35/6d/ae05a87a3ad540259c3ad88d71275cbd1c0f2d30ae04c65dcbfb6dcd4b9f/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd5415dded15c3822597455bc02bcd66e81ef8b7a48cb71a33628fc9fdde39df", size = 722230 }, - { url = "https://files.pythonhosted.org/packages/7f/b7/20c6f3c0b656fe609675d69bc135c03aac9e3865912444be6339207b6648/ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f66efbc1caa63c088dead1c4170d148eabc9b80d95fb75b6c92ac0aad2437d76", size = 686712 }, - { url = "https://files.pythonhosted.org/packages/cd/11/d12dbf683471f888d354dac59593873c2b45feb193c5e3e0f2ebf85e68b9/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:22353049ba4181685023b25b5b51a574bce33e7f51c759371a7422dcae5402a6", size = 663936 }, - { url = "https://files.pythonhosted.org/packages/72/14/4c268f5077db5c83f743ee1daeb236269fa8577133a5cfa49f8b382baf13/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:932205970b9f9991b34f55136be327501903f7c66830e9760a8ffb15b07f05cd", size = 696580 }, - { url = "https://files.pythonhosted.org/packages/30/fc/8cd12f189c6405a4c1cf37bd633aa740a9538c8e40497c231072d0fef5cf/ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a52d48f4e7bf9005e8f0a89209bf9a73f7190ddf0489eee5eb51377385f59f2a", size = 663393 }, - { url = "https://files.pythonhosted.org/packages/80/29/c0a017b704aaf3cbf704989785cd9c5d5b8ccec2dae6ac0c53833c84e677/ruamel.yaml.clib-0.2.12-cp310-cp310-win32.whl", hash = "sha256:3eac5a91891ceb88138c113f9db04f3cebdae277f5d44eaa3651a4f573e6a5da", size = 100326 }, - { url = "https://files.pythonhosted.org/packages/3a/65/fa39d74db4e2d0cd252355732d966a460a41cd01c6353b820a0952432839/ruamel.yaml.clib-0.2.12-cp310-cp310-win_amd64.whl", hash = "sha256:ab007f2f5a87bd08ab1499bdf96f3d5c6ad4dcfa364884cb4549aa0154b13a28", size = 118079 }, - { url = "https://files.pythonhosted.org/packages/fb/8f/683c6ad562f558cbc4f7c029abcd9599148c51c54b5ef0f24f2638da9fbb/ruamel.yaml.clib-0.2.12-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:4a6679521a58256a90b0d89e03992c15144c5f3858f40d7c18886023d7943db6", size = 132224 }, - { url = "https://files.pythonhosted.org/packages/3c/d2/b79b7d695e2f21da020bd44c782490578f300dd44f0a4c57a92575758a76/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:d84318609196d6bd6da0edfa25cedfbabd8dbde5140a0a23af29ad4b8f91fb1e", size = 641480 }, - { url = "https://files.pythonhosted.org/packages/68/6e/264c50ce2a31473a9fdbf4fa66ca9b2b17c7455b31ef585462343818bd6c/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb43a269eb827806502c7c8efb7ae7e9e9d0573257a46e8e952f4d4caba4f31e", size = 739068 }, - { url = "https://files.pythonhosted.org/packages/86/29/88c2567bc893c84d88b4c48027367c3562ae69121d568e8a3f3a8d363f4d/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:811ea1594b8a0fb466172c384267a4e5e367298af6b228931f273b111f17ef52", size = 703012 }, - { url = "https://files.pythonhosted.org/packages/11/46/879763c619b5470820f0cd6ca97d134771e502776bc2b844d2adb6e37753/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cf12567a7b565cbf65d438dec6cfbe2917d3c1bdddfce84a9930b7d35ea59642", size = 704352 }, - { url = "https://files.pythonhosted.org/packages/02/80/ece7e6034256a4186bbe50dee28cd032d816974941a6abf6a9d65e4228a7/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7dd5adc8b930b12c8fc5b99e2d535a09889941aa0d0bd06f4749e9a9397c71d2", size = 737344 }, - { url = "https://files.pythonhosted.org/packages/f0/ca/e4106ac7e80efbabdf4bf91d3d32fc424e41418458251712f5672eada9ce/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1492a6051dab8d912fc2adeef0e8c72216b24d57bd896ea607cb90bb0c4981d3", size = 714498 }, - { url = "https://files.pythonhosted.org/packages/67/58/b1f60a1d591b771298ffa0428237afb092c7f29ae23bad93420b1eb10703/ruamel.yaml.clib-0.2.12-cp311-cp311-win32.whl", hash = "sha256:bd0a08f0bab19093c54e18a14a10b4322e1eacc5217056f3c063bd2f59853ce4", size = 100205 }, - { url = "https://files.pythonhosted.org/packages/b4/4f/b52f634c9548a9291a70dfce26ca7ebce388235c93588a1068028ea23fcc/ruamel.yaml.clib-0.2.12-cp311-cp311-win_amd64.whl", hash = "sha256:a274fb2cb086c7a3dea4322ec27f4cb5cc4b6298adb583ab0e211a4682f241eb", size = 118185 }, - { url = "https://files.pythonhosted.org/packages/48/41/e7a405afbdc26af961678474a55373e1b323605a4f5e2ddd4a80ea80f628/ruamel.yaml.clib-0.2.12-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:20b0f8dc160ba83b6dcc0e256846e1a02d044e13f7ea74a3d1d56ede4e48c632", size = 133433 }, - { url = "https://files.pythonhosted.org/packages/ec/b0/b850385604334c2ce90e3ee1013bd911aedf058a934905863a6ea95e9eb4/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:943f32bc9dedb3abff9879edc134901df92cfce2c3d5c9348f172f62eb2d771d", size = 647362 }, - { url = "https://files.pythonhosted.org/packages/44/d0/3f68a86e006448fb6c005aee66565b9eb89014a70c491d70c08de597f8e4/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95c3829bb364fdb8e0332c9931ecf57d9be3519241323c5274bd82f709cebc0c", size = 754118 }, - { url = "https://files.pythonhosted.org/packages/52/a9/d39f3c5ada0a3bb2870d7db41901125dbe2434fa4f12ca8c5b83a42d7c53/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:749c16fcc4a2b09f28843cda5a193e0283e47454b63ec4b81eaa2242f50e4ccd", size = 706497 }, - { url = "https://files.pythonhosted.org/packages/b0/fa/097e38135dadd9ac25aecf2a54be17ddf6e4c23e43d538492a90ab3d71c6/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bf165fef1f223beae7333275156ab2022cffe255dcc51c27f066b4370da81e31", size = 698042 }, - { url = "https://files.pythonhosted.org/packages/ec/d5/a659ca6f503b9379b930f13bc6b130c9f176469b73b9834296822a83a132/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:32621c177bbf782ca5a18ba4d7af0f1082a3f6e517ac2a18b3974d4edf349680", size = 745831 }, - { url = "https://files.pythonhosted.org/packages/db/5d/36619b61ffa2429eeaefaab4f3374666adf36ad8ac6330d855848d7d36fd/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b82a7c94a498853aa0b272fd5bc67f29008da798d4f93a2f9f289feb8426a58d", size = 715692 }, - { url = "https://files.pythonhosted.org/packages/b1/82/85cb92f15a4231c89b95dfe08b09eb6adca929ef7df7e17ab59902b6f589/ruamel.yaml.clib-0.2.12-cp312-cp312-win32.whl", hash = "sha256:e8c4ebfcfd57177b572e2040777b8abc537cdef58a2120e830124946aa9b42c5", size = 98777 }, - { url = "https://files.pythonhosted.org/packages/d7/8f/c3654f6f1ddb75daf3922c3d8fc6005b1ab56671ad56ffb874d908bfa668/ruamel.yaml.clib-0.2.12-cp312-cp312-win_amd64.whl", hash = "sha256:0467c5965282c62203273b838ae77c0d29d7638c8a4e3a1c8bdd3602c10904e4", size = 115523 }, +sdist = { url = "https://files.pythonhosted.org/packages/20/84/80203abff8ea4993a87d823a5f632e4d92831ef75d404c9fc78d0176d2b5/ruamel.yaml.clib-0.2.12.tar.gz", hash = "sha256:6c8fbb13ec503f99a91901ab46e0b07ae7941cd527393187039aec586fdfd36f", size = 225315, upload-time = "2024-10-20T10:10:56.22Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/8f/683c6ad562f558cbc4f7c029abcd9599148c51c54b5ef0f24f2638da9fbb/ruamel.yaml.clib-0.2.12-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:4a6679521a58256a90b0d89e03992c15144c5f3858f40d7c18886023d7943db6", size = 132224, upload-time = "2024-10-20T10:12:45.162Z" }, + { url = "https://files.pythonhosted.org/packages/3c/d2/b79b7d695e2f21da020bd44c782490578f300dd44f0a4c57a92575758a76/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:d84318609196d6bd6da0edfa25cedfbabd8dbde5140a0a23af29ad4b8f91fb1e", size = 641480, upload-time = "2024-10-20T10:12:46.758Z" }, + { url = "https://files.pythonhosted.org/packages/68/6e/264c50ce2a31473a9fdbf4fa66ca9b2b17c7455b31ef585462343818bd6c/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb43a269eb827806502c7c8efb7ae7e9e9d0573257a46e8e952f4d4caba4f31e", size = 739068, upload-time = "2024-10-20T10:12:48.605Z" }, + { url = "https://files.pythonhosted.org/packages/86/29/88c2567bc893c84d88b4c48027367c3562ae69121d568e8a3f3a8d363f4d/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:811ea1594b8a0fb466172c384267a4e5e367298af6b228931f273b111f17ef52", size = 703012, upload-time = "2024-10-20T10:12:51.124Z" }, + { url = "https://files.pythonhosted.org/packages/11/46/879763c619b5470820f0cd6ca97d134771e502776bc2b844d2adb6e37753/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cf12567a7b565cbf65d438dec6cfbe2917d3c1bdddfce84a9930b7d35ea59642", size = 704352, upload-time = "2024-10-21T11:26:41.438Z" }, + { url = "https://files.pythonhosted.org/packages/02/80/ece7e6034256a4186bbe50dee28cd032d816974941a6abf6a9d65e4228a7/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7dd5adc8b930b12c8fc5b99e2d535a09889941aa0d0bd06f4749e9a9397c71d2", size = 737344, upload-time = "2024-10-21T11:26:43.62Z" }, + { url = "https://files.pythonhosted.org/packages/f0/ca/e4106ac7e80efbabdf4bf91d3d32fc424e41418458251712f5672eada9ce/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1492a6051dab8d912fc2adeef0e8c72216b24d57bd896ea607cb90bb0c4981d3", size = 714498, upload-time = "2024-12-11T19:58:15.592Z" }, + { url = "https://files.pythonhosted.org/packages/67/58/b1f60a1d591b771298ffa0428237afb092c7f29ae23bad93420b1eb10703/ruamel.yaml.clib-0.2.12-cp311-cp311-win32.whl", hash = "sha256:bd0a08f0bab19093c54e18a14a10b4322e1eacc5217056f3c063bd2f59853ce4", size = 100205, upload-time = "2024-10-20T10:12:52.865Z" }, + { url = "https://files.pythonhosted.org/packages/b4/4f/b52f634c9548a9291a70dfce26ca7ebce388235c93588a1068028ea23fcc/ruamel.yaml.clib-0.2.12-cp311-cp311-win_amd64.whl", hash = "sha256:a274fb2cb086c7a3dea4322ec27f4cb5cc4b6298adb583ab0e211a4682f241eb", size = 118185, upload-time = "2024-10-20T10:12:54.652Z" }, + { url = "https://files.pythonhosted.org/packages/48/41/e7a405afbdc26af961678474a55373e1b323605a4f5e2ddd4a80ea80f628/ruamel.yaml.clib-0.2.12-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:20b0f8dc160ba83b6dcc0e256846e1a02d044e13f7ea74a3d1d56ede4e48c632", size = 133433, upload-time = "2024-10-20T10:12:55.657Z" }, + { url = "https://files.pythonhosted.org/packages/ec/b0/b850385604334c2ce90e3ee1013bd911aedf058a934905863a6ea95e9eb4/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:943f32bc9dedb3abff9879edc134901df92cfce2c3d5c9348f172f62eb2d771d", size = 647362, upload-time = "2024-10-20T10:12:57.155Z" }, + { url = "https://files.pythonhosted.org/packages/44/d0/3f68a86e006448fb6c005aee66565b9eb89014a70c491d70c08de597f8e4/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95c3829bb364fdb8e0332c9931ecf57d9be3519241323c5274bd82f709cebc0c", size = 754118, upload-time = "2024-10-20T10:12:58.501Z" }, + { url = "https://files.pythonhosted.org/packages/52/a9/d39f3c5ada0a3bb2870d7db41901125dbe2434fa4f12ca8c5b83a42d7c53/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:749c16fcc4a2b09f28843cda5a193e0283e47454b63ec4b81eaa2242f50e4ccd", size = 706497, upload-time = "2024-10-20T10:13:00.211Z" }, + { url = "https://files.pythonhosted.org/packages/b0/fa/097e38135dadd9ac25aecf2a54be17ddf6e4c23e43d538492a90ab3d71c6/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bf165fef1f223beae7333275156ab2022cffe255dcc51c27f066b4370da81e31", size = 698042, upload-time = "2024-10-21T11:26:46.038Z" }, + { url = "https://files.pythonhosted.org/packages/ec/d5/a659ca6f503b9379b930f13bc6b130c9f176469b73b9834296822a83a132/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:32621c177bbf782ca5a18ba4d7af0f1082a3f6e517ac2a18b3974d4edf349680", size = 745831, upload-time = "2024-10-21T11:26:47.487Z" }, + { url = "https://files.pythonhosted.org/packages/db/5d/36619b61ffa2429eeaefaab4f3374666adf36ad8ac6330d855848d7d36fd/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b82a7c94a498853aa0b272fd5bc67f29008da798d4f93a2f9f289feb8426a58d", size = 715692, upload-time = "2024-12-11T19:58:17.252Z" }, + { url = "https://files.pythonhosted.org/packages/b1/82/85cb92f15a4231c89b95dfe08b09eb6adca929ef7df7e17ab59902b6f589/ruamel.yaml.clib-0.2.12-cp312-cp312-win32.whl", hash = "sha256:e8c4ebfcfd57177b572e2040777b8abc537cdef58a2120e830124946aa9b42c5", size = 98777, upload-time = "2024-10-20T10:13:01.395Z" }, + { url = "https://files.pythonhosted.org/packages/d7/8f/c3654f6f1ddb75daf3922c3d8fc6005b1ab56671ad56ffb874d908bfa668/ruamel.yaml.clib-0.2.12-cp312-cp312-win_amd64.whl", hash = "sha256:0467c5965282c62203273b838ae77c0d29d7638c8a4e3a1c8bdd3602c10904e4", size = 115523, upload-time = "2024-10-20T10:13:02.768Z" }, + { url = "https://files.pythonhosted.org/packages/29/00/4864119668d71a5fa45678f380b5923ff410701565821925c69780356ffa/ruamel.yaml.clib-0.2.12-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:4c8c5d82f50bb53986a5e02d1b3092b03622c02c2eb78e29bec33fd9593bae1a", size = 132011, upload-time = "2024-10-20T10:13:04.377Z" }, + { url = "https://files.pythonhosted.org/packages/7f/5e/212f473a93ae78c669ffa0cb051e3fee1139cb2d385d2ae1653d64281507/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux2014_aarch64.whl", hash = "sha256:e7e3736715fbf53e9be2a79eb4db68e4ed857017344d697e8b9749444ae57475", size = 642488, upload-time = "2024-10-20T10:13:05.906Z" }, + { url = "https://files.pythonhosted.org/packages/1f/8f/ecfbe2123ade605c49ef769788f79c38ddb1c8fa81e01f4dbf5cf1a44b16/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b7e75b4965e1d4690e93021adfcecccbca7d61c7bddd8e22406ef2ff20d74ef", size = 745066, upload-time = "2024-10-20T10:13:07.26Z" }, + { url = "https://files.pythonhosted.org/packages/e2/a9/28f60726d29dfc01b8decdb385de4ced2ced9faeb37a847bd5cf26836815/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96777d473c05ee3e5e3c3e999f5d23c6f4ec5b0c38c098b3a5229085f74236c6", size = 701785, upload-time = "2024-10-20T10:13:08.504Z" }, + { url = "https://files.pythonhosted.org/packages/84/7e/8e7ec45920daa7f76046578e4f677a3215fe8f18ee30a9cb7627a19d9b4c/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:3bc2a80e6420ca8b7d3590791e2dfc709c88ab9152c00eeb511c9875ce5778bf", size = 693017, upload-time = "2024-10-21T11:26:48.866Z" }, + { url = "https://files.pythonhosted.org/packages/c5/b3/d650eaade4ca225f02a648321e1ab835b9d361c60d51150bac49063b83fa/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:e188d2699864c11c36cdfdada94d781fd5d6b0071cd9c427bceb08ad3d7c70e1", size = 741270, upload-time = "2024-10-21T11:26:50.213Z" }, + { url = "https://files.pythonhosted.org/packages/87/b8/01c29b924dcbbed75cc45b30c30d565d763b9c4d540545a0eeecffb8f09c/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4f6f3eac23941b32afccc23081e1f50612bdbe4e982012ef4f5797986828cd01", size = 709059, upload-time = "2024-12-11T19:58:18.846Z" }, + { url = "https://files.pythonhosted.org/packages/30/8c/ed73f047a73638257aa9377ad356bea4d96125b305c34a28766f4445cc0f/ruamel.yaml.clib-0.2.12-cp313-cp313-win32.whl", hash = "sha256:6442cb36270b3afb1b4951f060eccca1ce49f3d087ca1ca4563a6eb479cb3de6", size = 98583, upload-time = "2024-10-20T10:13:09.658Z" }, + { url = "https://files.pythonhosted.org/packages/b0/85/e8e751d8791564dd333d5d9a4eab0a7a115f7e349595417fd50ecae3395c/ruamel.yaml.clib-0.2.12-cp313-cp313-win_amd64.whl", hash = "sha256:e5b8daf27af0b90da7bb903a876477a9e6d7270be6146906b276605997c7e9a3", size = 115190, upload-time = "2024-10-20T10:13:10.66Z" }, ] [[package]] name = "ruff" -version = "0.8.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b2/d6/a2373f3ba7180ddb44420d2a9d1f1510e1a4d162b3d27282bedcb09c8da9/ruff-0.8.0.tar.gz", hash = "sha256:a7ccfe6331bf8c8dad715753e157457faf7351c2b69f62f32c165c2dbcbacd44", size = 3276537 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/77/e889ee3ce7fd8baa3ed1b77a03b9fb8ec1be68be1418261522fd6a5405e0/ruff-0.8.0-py3-none-linux_armv6l.whl", hash = "sha256:fcb1bf2cc6706adae9d79c8d86478677e3bbd4ced796ccad106fd4776d395fea", size = 10518283 }, - { url = "https://files.pythonhosted.org/packages/da/c8/0a47de01edf19fb22f5f9b7964f46a68d0bdff20144d134556ffd1ba9154/ruff-0.8.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:295bb4c02d58ff2ef4378a1870c20af30723013f441c9d1637a008baaf928c8b", size = 10317691 }, - { url = "https://files.pythonhosted.org/packages/41/17/9885e4a0eeae07abd2a4ebabc3246f556719f24efa477ba2739146c4635a/ruff-0.8.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7b1f1c76b47c18fa92ee78b60d2d20d7e866c55ee603e7d19c1e991fad933a9a", size = 9940999 }, - { url = "https://files.pythonhosted.org/packages/3e/cd/46b6f7043597eb318b5f5482c8ae8f5491cccce771e85f59d23106f2d179/ruff-0.8.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb0d4f250a7711b67ad513fde67e8870109e5ce590a801c3722580fe98c33a99", size = 10772437 }, - { url = "https://files.pythonhosted.org/packages/5d/87/afc95aeb8bc78b1d8a3461717a4419c05aa8aa943d4c9cbd441630f85584/ruff-0.8.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0e55cce9aa93c5d0d4e3937e47b169035c7e91c8655b0974e61bb79cf398d49c", size = 10299156 }, - { url = "https://files.pythonhosted.org/packages/65/fa/04c647bb809c4d65e8eae1ed1c654d9481b21dd942e743cd33511687b9f9/ruff-0.8.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f4cd64916d8e732ce6b87f3f5296a8942d285bbbc161acee7fe561134af64f9", size = 11325819 }, - { url = "https://files.pythonhosted.org/packages/90/26/7dad6e7d833d391a8a1afe4ee70ca6f36c4a297d3cca83ef10e83e9aacf3/ruff-0.8.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c5c1466be2a2ebdf7c5450dd5d980cc87c8ba6976fb82582fea18823da6fa362", size = 12023927 }, - { url = "https://files.pythonhosted.org/packages/24/a0/be5296dda6428ba8a13bda8d09fbc0e14c810b485478733886e61597ae2b/ruff-0.8.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2dabfd05b96b7b8f2da00d53c514eea842bff83e41e1cceb08ae1966254a51df", size = 11589702 }, - { url = "https://files.pythonhosted.org/packages/26/3f/7602eb11d2886db545834182a9dbe500b8211fcbc9b4064bf9d358bbbbb4/ruff-0.8.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:facebdfe5a5af6b1588a1d26d170635ead6892d0e314477e80256ef4a8470cf3", size = 12782936 }, - { url = "https://files.pythonhosted.org/packages/4c/5d/083181bdec4ec92a431c1291d3fff65eef3ded630a4b55eb735000ef5f3b/ruff-0.8.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87a8e86bae0dbd749c815211ca11e3a7bd559b9710746c559ed63106d382bd9c", size = 11138488 }, - { url = "https://files.pythonhosted.org/packages/b7/23/c12cdef58413cee2436d6a177aa06f7a366ebbca916cf10820706f632459/ruff-0.8.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:85e654f0ded7befe2d61eeaf3d3b1e4ef3894469cd664ffa85006c7720f1e4a2", size = 10744474 }, - { url = "https://files.pythonhosted.org/packages/29/61/a12f3b81520083cd7c5caa24ba61bb99fd1060256482eff0ef04cc5ccd1b/ruff-0.8.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:83a55679c4cb449fa527b8497cadf54f076603cc36779b2170b24f704171ce70", size = 10369029 }, - { url = "https://files.pythonhosted.org/packages/08/2a/c013f4f3e4a54596c369cee74c24870ed1d534f31a35504908b1fc97017a/ruff-0.8.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:812e2052121634cf13cd6fddf0c1871d0ead1aad40a1a258753c04c18bb71bbd", size = 10867481 }, - { url = "https://files.pythonhosted.org/packages/d5/f7/685b1e1d42a3e94ceb25eab23c70bdd8c0ab66a43121ef83fe6db5a58756/ruff-0.8.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:780d5d8523c04202184405e60c98d7595bdb498c3c6abba3b6d4cdf2ca2af426", size = 11237117 }, - { url = "https://files.pythonhosted.org/packages/03/20/401132c0908e8837625e3b7e32df9962e7cd681a4df1e16a10e2a5b4ecda/ruff-0.8.0-py3-none-win32.whl", hash = "sha256:5fdb6efecc3eb60bba5819679466471fd7d13c53487df7248d6e27146e985468", size = 8783511 }, - { url = "https://files.pythonhosted.org/packages/1d/5c/4d800fca7854f62ad77f2c0d99b4b585f03e2d87a6ec1ecea85543a14a3c/ruff-0.8.0-py3-none-win_amd64.whl", hash = "sha256:582891c57b96228d146725975fbb942e1f30a0c4ba19722e692ca3eb25cc9b4f", size = 9559876 }, - { url = "https://files.pythonhosted.org/packages/5b/bc/cc8a6a5ca4960b226dc15dd8fb511dd11f2014ff89d325c0b9b9faa9871f/ruff-0.8.0-py3-none-win_arm64.whl", hash = "sha256:ba93e6294e9a737cd726b74b09a6972e36bb511f9a102f1d9a7e1ce94dd206a6", size = 8939733 }, +version = "0.12.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/de/55/16ab6a7d88d93001e1ae4c34cbdcfb376652d761799459ff27c1dc20f6fa/ruff-0.12.11.tar.gz", hash = "sha256:c6b09ae8426a65bbee5425b9d0b82796dbb07cb1af045743c79bfb163001165d", size = 5347103, upload-time = "2025-08-28T13:59:08.87Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d6/a2/3b3573e474de39a7a475f3fbaf36a25600bfeb238e1a90392799163b64a0/ruff-0.12.11-py3-none-linux_armv6l.whl", hash = "sha256:93fce71e1cac3a8bf9200e63a38ac5c078f3b6baebffb74ba5274fb2ab276065", size = 11979885, upload-time = "2025-08-28T13:58:26.654Z" }, + { url = "https://files.pythonhosted.org/packages/76/e4/235ad6d1785a2012d3ded2350fd9bc5c5af8c6f56820e696b0118dfe7d24/ruff-0.12.11-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b8e33ac7b28c772440afa80cebb972ffd823621ded90404f29e5ab6d1e2d4b93", size = 12742364, upload-time = "2025-08-28T13:58:30.256Z" }, + { url = "https://files.pythonhosted.org/packages/2c/0d/15b72c5fe6b1e402a543aa9d8960e0a7e19dfb079f5b0b424db48b7febab/ruff-0.12.11-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d69fb9d4937aa19adb2e9f058bc4fbfe986c2040acb1a4a9747734834eaa0bfd", size = 11920111, upload-time = "2025-08-28T13:58:33.677Z" }, + { url = "https://files.pythonhosted.org/packages/3e/c0/f66339d7893798ad3e17fa5a1e587d6fd9806f7c1c062b63f8b09dda6702/ruff-0.12.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:411954eca8464595077a93e580e2918d0a01a19317af0a72132283e28ae21bee", size = 12160060, upload-time = "2025-08-28T13:58:35.74Z" }, + { url = "https://files.pythonhosted.org/packages/03/69/9870368326db26f20c946205fb2d0008988aea552dbaec35fbacbb46efaa/ruff-0.12.11-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6a2c0a2e1a450f387bf2c6237c727dd22191ae8c00e448e0672d624b2bbd7fb0", size = 11799848, upload-time = "2025-08-28T13:58:38.051Z" }, + { url = "https://files.pythonhosted.org/packages/25/8c/dd2c7f990e9b3a8a55eee09d4e675027d31727ce33cdb29eab32d025bdc9/ruff-0.12.11-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ca4c3a7f937725fd2413c0e884b5248a19369ab9bdd850b5781348ba283f644", size = 13536288, upload-time = "2025-08-28T13:58:40.046Z" }, + { url = "https://files.pythonhosted.org/packages/7a/30/d5496fa09aba59b5e01ea76775a4c8897b13055884f56f1c35a4194c2297/ruff-0.12.11-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:4d1df0098124006f6a66ecf3581a7f7e754c4df7644b2e6704cd7ca80ff95211", size = 14490633, upload-time = "2025-08-28T13:58:42.285Z" }, + { url = "https://files.pythonhosted.org/packages/9b/2f/81f998180ad53445d403c386549d6946d0748e536d58fce5b5e173511183/ruff-0.12.11-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5a8dd5f230efc99a24ace3b77e3555d3fbc0343aeed3fc84c8d89e75ab2ff793", size = 13888430, upload-time = "2025-08-28T13:58:44.641Z" }, + { url = "https://files.pythonhosted.org/packages/87/71/23a0d1d5892a377478c61dbbcffe82a3476b050f38b5162171942a029ef3/ruff-0.12.11-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4dc75533039d0ed04cd33fb8ca9ac9620b99672fe7ff1533b6402206901c34ee", size = 12913133, upload-time = "2025-08-28T13:58:47.039Z" }, + { url = "https://files.pythonhosted.org/packages/80/22/3c6cef96627f89b344c933781ed38329bfb87737aa438f15da95907cbfd5/ruff-0.12.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4fc58f9266d62c6eccc75261a665f26b4ef64840887fc6cbc552ce5b29f96cc8", size = 13169082, upload-time = "2025-08-28T13:58:49.157Z" }, + { url = "https://files.pythonhosted.org/packages/05/b5/68b3ff96160d8b49e8dd10785ff3186be18fd650d356036a3770386e6c7f/ruff-0.12.11-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:5a0113bd6eafd545146440225fe60b4e9489f59eb5f5f107acd715ba5f0b3d2f", size = 13139490, upload-time = "2025-08-28T13:58:51.593Z" }, + { url = "https://files.pythonhosted.org/packages/59/b9/050a3278ecd558f74f7ee016fbdf10591d50119df8d5f5da45a22c6afafc/ruff-0.12.11-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:0d737b4059d66295c3ea5720e6efc152623bb83fde5444209b69cd33a53e2000", size = 11958928, upload-time = "2025-08-28T13:58:53.943Z" }, + { url = "https://files.pythonhosted.org/packages/f9/bc/93be37347db854806904a43b0493af8d6873472dfb4b4b8cbb27786eb651/ruff-0.12.11-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:916fc5defee32dbc1fc1650b576a8fed68f5e8256e2180d4d9855aea43d6aab2", size = 11764513, upload-time = "2025-08-28T13:58:55.976Z" }, + { url = "https://files.pythonhosted.org/packages/7a/a1/1471751e2015a81fd8e166cd311456c11df74c7e8769d4aabfbc7584c7ac/ruff-0.12.11-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c984f07d7adb42d3ded5be894fb4007f30f82c87559438b4879fe7aa08c62b39", size = 12745154, upload-time = "2025-08-28T13:58:58.16Z" }, + { url = "https://files.pythonhosted.org/packages/68/ab/2542b14890d0f4872dd81b7b2a6aed3ac1786fae1ce9b17e11e6df9e31e3/ruff-0.12.11-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e07fbb89f2e9249f219d88331c833860489b49cdf4b032b8e4432e9b13e8a4b9", size = 13227653, upload-time = "2025-08-28T13:59:00.276Z" }, + { url = "https://files.pythonhosted.org/packages/22/16/2fbfc61047dbfd009c58a28369a693a1484ad15441723be1cd7fe69bb679/ruff-0.12.11-py3-none-win32.whl", hash = "sha256:c792e8f597c9c756e9bcd4d87cf407a00b60af77078c96f7b6366ea2ce9ba9d3", size = 11944270, upload-time = "2025-08-28T13:59:02.347Z" }, + { url = "https://files.pythonhosted.org/packages/08/a5/34276984705bfe069cd383101c45077ee029c3fe3b28225bf67aa35f0647/ruff-0.12.11-py3-none-win_amd64.whl", hash = "sha256:a3283325960307915b6deb3576b96919ee89432ebd9c48771ca12ee8afe4a0fd", size = 13046600, upload-time = "2025-08-28T13:59:04.751Z" }, + { url = "https://files.pythonhosted.org/packages/84/a8/001d4a7c2b37623a3fd7463208267fb906df40ff31db496157549cfd6e72/ruff-0.12.11-py3-none-win_arm64.whl", hash = "sha256:bae4d6e6a2676f8fb0f98b74594a048bae1b944aab17e9f5d504062303c6dbea", size = 12135290, upload-time = "2025-08-28T13:59:06.933Z" }, ] [[package]] name = "scanpy" -version = "1.10.4" +version = "1.11.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anndata" }, @@ -2482,19 +2968,20 @@ dependencies = [ { name = "scikit-learn" }, { name = "scipy" }, { name = "seaborn" }, - { name = "session-info" }, + { name = "session-info2" }, { name = "statsmodels" }, { name = "tqdm" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, { name = "umap-learn" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fd/cb/213db09685b572ef6470a5fa9199653949e7842e32c12f6dd1a55d80fea6/scanpy-1.10.4.tar.gz", hash = "sha256:2682fbbe2e4106c349472feebef08e174062fb666db4c94123758c6a7a470396", size = 13638355 } +sdist = { url = "https://files.pythonhosted.org/packages/8e/1a/1570cba6fc910853dd0296c48a0700b75e4f5398d6f8a8e5ee8193b36bca/scanpy-1.11.4.tar.gz", hash = "sha256:333189ecac9c7009bf55d416ee2e272e1c490d54c719478f7b4dd1fc294d2f95", size = 14091636, upload-time = "2025-07-30T14:34:30.496Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/b4/c408bac643afd670d2009219dbbb2076290e23fb1986937825c9a0d839c5/scanpy-1.10.4-py3-none-any.whl", hash = "sha256:d93256d0e8e6e34639ff9bf20bdde0162b5162c6f18f151d90b3eb9ea54ff03a", size = 2085671 }, + { url = "https://files.pythonhosted.org/packages/e6/d0/af2ebd8750a9a5e4ce88b54265047e858d7217f81b83613bba27e1a8ba2e/scanpy-1.11.4-py3-none-any.whl", hash = "sha256:f4ab68ab89e97e88a4faed07b1bc51533fb2e67f797a65a4683591910abfab95", size = 2102520, upload-time = "2025-07-30T14:34:28.155Z" }, ] [[package]] name = "scikit-learn" -version = "1.5.2" +version = "1.7.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "joblib" }, @@ -2502,58 +2989,87 @@ dependencies = [ { name = "scipy" }, { name = "threadpoolctl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/37/59/44985a2bdc95c74e34fef3d10cb5d93ce13b0e2a7baefffe1b53853b502d/scikit_learn-1.5.2.tar.gz", hash = "sha256:b4237ed7b3fdd0a4882792e68ef2545d5baa50aca3bb45aa7df468138ad8f94d", size = 7001680 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/98/89/be41419b4bec629a4691183a5eb1796f91252a13a5ffa243fd958cad7e91/scikit_learn-1.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:299406827fb9a4f862626d0fe6c122f5f87f8910b86fe5daa4c32dcd742139b6", size = 12106070 }, - { url = "https://files.pythonhosted.org/packages/bf/e0/3b6d777d375f3b685f433c93384cdb724fb078e1dc8f8ff0950467e56c30/scikit_learn-1.5.2-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:2d4cad1119c77930b235579ad0dc25e65c917e756fe80cab96aa3b9428bd3fb0", size = 10971758 }, - { url = "https://files.pythonhosted.org/packages/7b/31/eb7dd56c371640753953277de11356c46a3149bfeebb3d7dcd90b993715a/scikit_learn-1.5.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c412ccc2ad9bf3755915e3908e677b367ebc8d010acbb3f182814524f2e5540", size = 12500080 }, - { url = "https://files.pythonhosted.org/packages/4c/1e/a7c7357e704459c7d56a18df4a0bf08669442d1f8878cc0864beccd6306a/scikit_learn-1.5.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a686885a4b3818d9e62904d91b57fa757fc2bed3e465c8b177be652f4dd37c8", size = 13347241 }, - { url = "https://files.pythonhosted.org/packages/48/76/154ebda6794faf0b0f3ccb1b5cd9a19f0a63cb9e1f3d2c61b6114002677b/scikit_learn-1.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:c15b1ca23d7c5f33cc2cb0a0d6aaacf893792271cddff0edbd6a40e8319bc113", size = 11000477 }, - { url = "https://files.pythonhosted.org/packages/ff/91/609961972f694cb9520c4c3d201e377a26583e1eb83bc5a334c893729214/scikit_learn-1.5.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:03b6158efa3faaf1feea3faa884c840ebd61b6484167c711548fce208ea09445", size = 12088580 }, - { url = "https://files.pythonhosted.org/packages/cd/7a/19fe32c810c5ceddafcfda16276d98df299c8649e24e84d4f00df4a91e01/scikit_learn-1.5.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:1ff45e26928d3b4eb767a8f14a9a6efbf1cbff7c05d1fb0f95f211a89fd4f5de", size = 10975994 }, - { url = "https://files.pythonhosted.org/packages/4c/75/62e49f8a62bf3c60b0e64d0fce540578ee4f0e752765beb2e1dc7c6d6098/scikit_learn-1.5.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f763897fe92d0e903aa4847b0aec0e68cadfff77e8a0687cabd946c89d17e675", size = 12465782 }, - { url = "https://files.pythonhosted.org/packages/49/21/3723de321531c9745e40f1badafd821e029d346155b6c79704e0b7197552/scikit_learn-1.5.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8b0ccd4a902836493e026c03256e8b206656f91fbcc4fde28c57a5b752561f1", size = 13322034 }, - { url = "https://files.pythonhosted.org/packages/17/1c/ccdd103cfcc9435a18819856fbbe0c20b8fa60bfc3343580de4be13f0668/scikit_learn-1.5.2-cp311-cp311-win_amd64.whl", hash = "sha256:6c16d84a0d45e4894832b3c4d0bf73050939e21b99b01b6fd59cbb0cf39163b6", size = 11015224 }, - { url = "https://files.pythonhosted.org/packages/a4/db/b485c1ac54ff3bd9e7e6b39d3cc6609c4c76a65f52ab0a7b22b6c3ab0e9d/scikit_learn-1.5.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f932a02c3f4956dfb981391ab24bda1dbd90fe3d628e4b42caef3e041c67707a", size = 12110344 }, - { url = "https://files.pythonhosted.org/packages/54/1a/7deb52fa23aebb855431ad659b3c6a2e1709ece582cb3a63d66905e735fe/scikit_learn-1.5.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:3b923d119d65b7bd555c73be5423bf06c0105678ce7e1f558cb4b40b0a5502b1", size = 11033502 }, - { url = "https://files.pythonhosted.org/packages/a1/32/4a7a205b14c11225609b75b28402c196e4396ac754dab6a81971b811781c/scikit_learn-1.5.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f60021ec1574e56632be2a36b946f8143bf4e5e6af4a06d85281adc22938e0dd", size = 12085794 }, - { url = "https://files.pythonhosted.org/packages/c6/29/044048c5e911373827c0e1d3051321b9183b2a4f8d4e2f11c08fcff83f13/scikit_learn-1.5.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:394397841449853c2290a32050382edaec3da89e35b3e03d6cc966aebc6a8ae6", size = 12945797 }, - { url = "https://files.pythonhosted.org/packages/aa/ce/c0b912f2f31aeb1b756a6ba56bcd84dd1f8a148470526a48515a3f4d48cd/scikit_learn-1.5.2-cp312-cp312-win_amd64.whl", hash = "sha256:57cc1786cfd6bd118220a92ede80270132aa353647684efa385a74244a41e3b1", size = 10985467 }, +sdist = { url = "https://files.pythonhosted.org/packages/41/84/5f4af978fff619706b8961accac84780a6d298d82a8873446f72edb4ead0/scikit_learn-1.7.1.tar.gz", hash = "sha256:24b3f1e976a4665aa74ee0fcaac2b8fccc6ae77c8e07ab25da3ba6d3292b9802", size = 7190445, upload-time = "2025-07-18T08:01:54.5Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b4/bd/a23177930abd81b96daffa30ef9c54ddbf544d3226b8788ce4c3ef1067b4/scikit_learn-1.7.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:90c8494ea23e24c0fb371afc474618c1019dc152ce4a10e4607e62196113851b", size = 9334838, upload-time = "2025-07-18T08:01:11.239Z" }, + { url = "https://files.pythonhosted.org/packages/8d/a1/d3a7628630a711e2ac0d1a482910da174b629f44e7dd8cfcd6924a4ef81a/scikit_learn-1.7.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:bb870c0daf3bf3be145ec51df8ac84720d9972170786601039f024bf6d61a518", size = 8651241, upload-time = "2025-07-18T08:01:13.234Z" }, + { url = "https://files.pythonhosted.org/packages/26/92/85ec172418f39474c1cd0221d611345d4f433fc4ee2fc68e01f524ccc4e4/scikit_learn-1.7.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:40daccd1b5623f39e8943ab39735cadf0bdce80e67cdca2adcb5426e987320a8", size = 9718677, upload-time = "2025-07-18T08:01:15.649Z" }, + { url = "https://files.pythonhosted.org/packages/df/ce/abdb1dcbb1d2b66168ec43b23ee0cee356b4cc4100ddee3943934ebf1480/scikit_learn-1.7.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:30d1f413cfc0aa5a99132a554f1d80517563c34a9d3e7c118fde2d273c6fe0f7", size = 9511189, upload-time = "2025-07-18T08:01:18.013Z" }, + { url = "https://files.pythonhosted.org/packages/b2/3b/47b5eaee01ef2b5a80ba3f7f6ecf79587cb458690857d4777bfd77371c6f/scikit_learn-1.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:c711d652829a1805a95d7fe96654604a8f16eab5a9e9ad87b3e60173415cb650", size = 8914794, upload-time = "2025-07-18T08:01:20.357Z" }, + { url = "https://files.pythonhosted.org/packages/cb/16/57f176585b35ed865f51b04117947fe20f130f78940c6477b6d66279c9c2/scikit_learn-1.7.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3cee419b49b5bbae8796ecd690f97aa412ef1674410c23fc3257c6b8b85b8087", size = 9260431, upload-time = "2025-07-18T08:01:22.77Z" }, + { url = "https://files.pythonhosted.org/packages/67/4e/899317092f5efcab0e9bc929e3391341cec8fb0e816c4789686770024580/scikit_learn-1.7.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:2fd8b8d35817b0d9ebf0b576f7d5ffbbabdb55536b0655a8aaae629d7ffd2e1f", size = 8637191, upload-time = "2025-07-18T08:01:24.731Z" }, + { url = "https://files.pythonhosted.org/packages/f3/1b/998312db6d361ded1dd56b457ada371a8d8d77ca2195a7d18fd8a1736f21/scikit_learn-1.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:588410fa19a96a69763202f1d6b7b91d5d7a5d73be36e189bc6396bfb355bd87", size = 9486346, upload-time = "2025-07-18T08:01:26.713Z" }, + { url = "https://files.pythonhosted.org/packages/ad/09/a2aa0b4e644e5c4ede7006748f24e72863ba2ae71897fecfd832afea01b4/scikit_learn-1.7.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e3142f0abe1ad1d1c31a2ae987621e41f6b578144a911ff4ac94781a583adad7", size = 9290988, upload-time = "2025-07-18T08:01:28.938Z" }, + { url = "https://files.pythonhosted.org/packages/15/fa/c61a787e35f05f17fc10523f567677ec4eeee5f95aa4798dbbbcd9625617/scikit_learn-1.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:3ddd9092c1bd469acab337d87930067c87eac6bd544f8d5027430983f1e1ae88", size = 8735568, upload-time = "2025-07-18T08:01:30.936Z" }, + { url = "https://files.pythonhosted.org/packages/52/f8/e0533303f318a0f37b88300d21f79b6ac067188d4824f1047a37214ab718/scikit_learn-1.7.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b7839687fa46d02e01035ad775982f2470be2668e13ddd151f0f55a5bf123bae", size = 9213143, upload-time = "2025-07-18T08:01:32.942Z" }, + { url = "https://files.pythonhosted.org/packages/71/f3/f1df377d1bdfc3e3e2adc9c119c238b182293e6740df4cbeac6de2cc3e23/scikit_learn-1.7.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:a10f276639195a96c86aa572ee0698ad64ee939a7b042060b98bd1930c261d10", size = 8591977, upload-time = "2025-07-18T08:01:34.967Z" }, + { url = "https://files.pythonhosted.org/packages/99/72/c86a4cd867816350fe8dee13f30222340b9cd6b96173955819a5561810c5/scikit_learn-1.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:13679981fdaebc10cc4c13c43344416a86fcbc61449cb3e6517e1df9d12c8309", size = 9436142, upload-time = "2025-07-18T08:01:37.397Z" }, + { url = "https://files.pythonhosted.org/packages/e8/66/277967b29bd297538dc7a6ecfb1a7dce751beabd0d7f7a2233be7a4f7832/scikit_learn-1.7.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4f1262883c6a63f067a980a8cdd2d2e7f2513dddcef6a9eaada6416a7a7cbe43", size = 9282996, upload-time = "2025-07-18T08:01:39.721Z" }, + { url = "https://files.pythonhosted.org/packages/e2/47/9291cfa1db1dae9880420d1e07dbc7e8dd4a7cdbc42eaba22512e6bde958/scikit_learn-1.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:ca6d31fb10e04d50bfd2b50d66744729dbb512d4efd0223b864e2fdbfc4cee11", size = 8707418, upload-time = "2025-07-18T08:01:42.124Z" }, + { url = "https://files.pythonhosted.org/packages/61/95/45726819beccdaa34d3362ea9b2ff9f2b5d3b8bf721bd632675870308ceb/scikit_learn-1.7.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:781674d096303cfe3d351ae6963ff7c958db61cde3421cd490e3a5a58f2a94ae", size = 9561466, upload-time = "2025-07-18T08:01:44.195Z" }, + { url = "https://files.pythonhosted.org/packages/ee/1c/6f4b3344805de783d20a51eb24d4c9ad4b11a7f75c1801e6ec6d777361fd/scikit_learn-1.7.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:10679f7f125fe7ecd5fad37dd1aa2daae7e3ad8df7f3eefa08901b8254b3e12c", size = 9040467, upload-time = "2025-07-18T08:01:46.671Z" }, + { url = "https://files.pythonhosted.org/packages/6f/80/abe18fe471af9f1d181904203d62697998b27d9b62124cd281d740ded2f9/scikit_learn-1.7.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1f812729e38c8cb37f760dce71a9b83ccfb04f59b3dca7c6079dcdc60544fa9e", size = 9532052, upload-time = "2025-07-18T08:01:48.676Z" }, + { url = "https://files.pythonhosted.org/packages/14/82/b21aa1e0c4cee7e74864d3a5a721ab8fcae5ca55033cb6263dca297ed35b/scikit_learn-1.7.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:88e1a20131cf741b84b89567e1717f27a2ced228e0f29103426102bc2e3b8ef7", size = 9361575, upload-time = "2025-07-18T08:01:50.639Z" }, + { url = "https://files.pythonhosted.org/packages/f2/20/f4777fcd5627dc6695fa6b92179d0edb7a3ac1b91bcd9a1c7f64fa7ade23/scikit_learn-1.7.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b1bd1d919210b6a10b7554b717c9000b5485aa95a1d0f177ae0d7ee8ec750da5", size = 9277310, upload-time = "2025-07-18T08:01:52.547Z" }, ] [[package]] name = "scipy" -version = "1.14.1" +version = "1.16.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/62/11/4d44a1f274e002784e4dbdb81e0ea96d2de2d1045b2132d5af62cc31fd28/scipy-1.14.1.tar.gz", hash = "sha256:5a275584e726026a5699459aa72f828a610821006228e841b94275c4a7c08417", size = 58620554 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/64/68/3bc0cfaf64ff507d82b1e5d5b64521df4c8bf7e22bc0b897827cbee9872c/scipy-1.14.1-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:b28d2ca4add7ac16ae8bb6632a3c86e4b9e4d52d3e34267f6e1b0c1f8d87e389", size = 39069598 }, - { url = "https://files.pythonhosted.org/packages/43/a5/8d02f9c372790326ad405d94f04d4339482ec082455b9e6e288f7100513b/scipy-1.14.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:d0d2821003174de06b69e58cef2316a6622b60ee613121199cb2852a873f8cf3", size = 29879676 }, - { url = "https://files.pythonhosted.org/packages/07/42/0e0bea9666fcbf2cb6ea0205db42c81b1f34d7b729ba251010edf9c80ebd/scipy-1.14.1-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:8bddf15838ba768bb5f5083c1ea012d64c9a444e16192762bd858f1e126196d0", size = 23088696 }, - { url = "https://files.pythonhosted.org/packages/15/47/298ab6fef5ebf31b426560e978b8b8548421d4ed0bf99263e1eb44532306/scipy-1.14.1-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:97c5dddd5932bd2a1a31c927ba5e1463a53b87ca96b5c9bdf5dfd6096e27efc3", size = 25470699 }, - { url = "https://files.pythonhosted.org/packages/d8/df/cdb6be5274bc694c4c22862ac3438cb04f360ed9df0aecee02ce0b798380/scipy-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ff0a7e01e422c15739ecd64432743cf7aae2b03f3084288f399affcefe5222d", size = 35606631 }, - { url = "https://files.pythonhosted.org/packages/47/78/b0c2c23880dd1e99e938ad49ccfb011ae353758a2dc5ed7ee59baff684c3/scipy-1.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e32dced201274bf96899e6491d9ba3e9a5f6b336708656466ad0522d8528f69", size = 41178528 }, - { url = "https://files.pythonhosted.org/packages/5d/aa/994b45c34b897637b853ec04334afa55a85650a0d11dacfa67232260fb0a/scipy-1.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8426251ad1e4ad903a4514712d2fa8fdd5382c978010d1c6f5f37ef286a713ad", size = 42784535 }, - { url = "https://files.pythonhosted.org/packages/e7/1c/8daa6df17a945cb1a2a1e3bae3c49643f7b3b94017ff01a4787064f03f84/scipy-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:a49f6ed96f83966f576b33a44257d869756df6cf1ef4934f59dd58b25e0327e5", size = 44772117 }, - { url = "https://files.pythonhosted.org/packages/b2/ab/070ccfabe870d9f105b04aee1e2860520460ef7ca0213172abfe871463b9/scipy-1.14.1-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:2da0469a4ef0ecd3693761acbdc20f2fdeafb69e6819cc081308cc978153c675", size = 39076999 }, - { url = "https://files.pythonhosted.org/packages/a7/c5/02ac82f9bb8f70818099df7e86c3ad28dae64e1347b421d8e3adf26acab6/scipy-1.14.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:c0ee987efa6737242745f347835da2cc5bb9f1b42996a4d97d5c7ff7928cb6f2", size = 29894570 }, - { url = "https://files.pythonhosted.org/packages/ed/05/7f03e680cc5249c4f96c9e4e845acde08eb1aee5bc216eff8a089baa4ddb/scipy-1.14.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3a1b111fac6baec1c1d92f27e76511c9e7218f1695d61b59e05e0fe04dc59617", size = 23103567 }, - { url = "https://files.pythonhosted.org/packages/5e/fc/9f1413bef53171f379d786aabc104d4abeea48ee84c553a3e3d8c9f96a9c/scipy-1.14.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:8475230e55549ab3f207bff11ebfc91c805dc3463ef62eda3ccf593254524ce8", size = 25499102 }, - { url = "https://files.pythonhosted.org/packages/c2/4b/b44bee3c2ddc316b0159b3d87a3d467ef8d7edfd525e6f7364a62cd87d90/scipy-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:278266012eb69f4a720827bdd2dc54b2271c97d84255b2faaa8f161a158c3b37", size = 35586346 }, - { url = "https://files.pythonhosted.org/packages/93/6b/701776d4bd6bdd9b629c387b5140f006185bd8ddea16788a44434376b98f/scipy-1.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fef8c87f8abfb884dac04e97824b61299880c43f4ce675dd2cbeadd3c9b466d2", size = 41165244 }, - { url = "https://files.pythonhosted.org/packages/06/57/e6aa6f55729a8f245d8a6984f2855696c5992113a5dc789065020f8be753/scipy-1.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b05d43735bb2f07d689f56f7b474788a13ed8adc484a85aa65c0fd931cf9ccd2", size = 42817917 }, - { url = "https://files.pythonhosted.org/packages/ea/c2/5ecadc5fcccefaece775feadcd795060adf5c3b29a883bff0e678cfe89af/scipy-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:716e389b694c4bb564b4fc0c51bc84d381735e0d39d3f26ec1af2556ec6aad94", size = 44781033 }, - { url = "https://files.pythonhosted.org/packages/c0/04/2bdacc8ac6387b15db6faa40295f8bd25eccf33f1f13e68a72dc3c60a99e/scipy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:631f07b3734d34aced009aaf6fedfd0eb3498a97e581c3b1e5f14a04164a456d", size = 39128781 }, - { url = "https://files.pythonhosted.org/packages/c8/53/35b4d41f5fd42f5781dbd0dd6c05d35ba8aa75c84ecddc7d44756cd8da2e/scipy-1.14.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:af29a935803cc707ab2ed7791c44288a682f9c8107bc00f0eccc4f92c08d6e07", size = 29939542 }, - { url = "https://files.pythonhosted.org/packages/66/67/6ef192e0e4d77b20cc33a01e743b00bc9e68fb83b88e06e636d2619a8767/scipy-1.14.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:2843f2d527d9eebec9a43e6b406fb7266f3af25a751aa91d62ff416f54170bc5", size = 23148375 }, - { url = "https://files.pythonhosted.org/packages/f6/32/3a6dedd51d68eb7b8e7dc7947d5d841bcb699f1bf4463639554986f4d782/scipy-1.14.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:eb58ca0abd96911932f688528977858681a59d61a7ce908ffd355957f7025cfc", size = 25578573 }, - { url = "https://files.pythonhosted.org/packages/f0/5a/efa92a58dc3a2898705f1dc9dbaf390ca7d4fba26d6ab8cfffb0c72f656f/scipy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30ac8812c1d2aab7131a79ba62933a2a76f582d5dbbc695192453dae67ad6310", size = 35319299 }, - { url = "https://files.pythonhosted.org/packages/8e/ee/8a26858ca517e9c64f84b4c7734b89bda8e63bec85c3d2f432d225bb1886/scipy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f9ea80f2e65bdaa0b7627fb00cbeb2daf163caa015e59b7516395fe3bd1e066", size = 40849331 }, - { url = "https://files.pythonhosted.org/packages/a5/cd/06f72bc9187840f1c99e1a8750aad4216fc7dfdd7df46e6280add14b4822/scipy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:edaf02b82cd7639db00dbff629995ef185c8df4c3ffa71a5562a595765a06ce1", size = 42544049 }, - { url = "https://files.pythonhosted.org/packages/aa/7d/43ab67228ef98c6b5dd42ab386eae2d7877036970a0d7e3dd3eb47a0d530/scipy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:2ff38e22128e6c03ff73b6bb0f85f897d2362f8c052e3b8ad00532198fbdae3f", size = 44521212 }, +sdist = { url = "https://files.pythonhosted.org/packages/f5/4a/b927028464795439faec8eaf0b03b011005c487bb2d07409f28bf30879c4/scipy-1.16.1.tar.gz", hash = "sha256:44c76f9e8b6e8e488a586190ab38016e4ed2f8a038af7cd3defa903c0a2238b3", size = 30580861, upload-time = "2025-07-27T16:33:30.834Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/da/91/812adc6f74409b461e3a5fa97f4f74c769016919203138a3bf6fc24ba4c5/scipy-1.16.1-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:c033fa32bab91dc98ca59d0cf23bb876454e2bb02cbe592d5023138778f70030", size = 36552519, upload-time = "2025-07-27T16:26:29.658Z" }, + { url = "https://files.pythonhosted.org/packages/47/18/8e355edcf3b71418d9e9f9acd2708cc3a6c27e8f98fde0ac34b8a0b45407/scipy-1.16.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:6e5c2f74e5df33479b5cd4e97a9104c511518fbd979aa9b8f6aec18b2e9ecae7", size = 28638010, upload-time = "2025-07-27T16:26:38.196Z" }, + { url = "https://files.pythonhosted.org/packages/d9/eb/e931853058607bdfbc11b86df19ae7a08686121c203483f62f1ecae5989c/scipy-1.16.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:0a55ffe0ba0f59666e90951971a884d1ff6f4ec3275a48f472cfb64175570f77", size = 20909790, upload-time = "2025-07-27T16:26:43.93Z" }, + { url = "https://files.pythonhosted.org/packages/45/0c/be83a271d6e96750cd0be2e000f35ff18880a46f05ce8b5d3465dc0f7a2a/scipy-1.16.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:f8a5d6cd147acecc2603fbd382fed6c46f474cccfcf69ea32582e033fb54dcfe", size = 23513352, upload-time = "2025-07-27T16:26:50.017Z" }, + { url = "https://files.pythonhosted.org/packages/7c/bf/fe6eb47e74f762f933cca962db7f2c7183acfdc4483bd1c3813cfe83e538/scipy-1.16.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cb18899127278058bcc09e7b9966d41a5a43740b5bb8dcba401bd983f82e885b", size = 33534643, upload-time = "2025-07-27T16:26:57.503Z" }, + { url = "https://files.pythonhosted.org/packages/bb/ba/63f402e74875486b87ec6506a4f93f6d8a0d94d10467280f3d9d7837ce3a/scipy-1.16.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:adccd93a2fa937a27aae826d33e3bfa5edf9aa672376a4852d23a7cd67a2e5b7", size = 35376776, upload-time = "2025-07-27T16:27:06.639Z" }, + { url = "https://files.pythonhosted.org/packages/c3/b4/04eb9d39ec26a1b939689102da23d505ea16cdae3dbb18ffc53d1f831044/scipy-1.16.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:18aca1646a29ee9a0625a1be5637fa798d4d81fdf426481f06d69af828f16958", size = 35698906, upload-time = "2025-07-27T16:27:14.943Z" }, + { url = "https://files.pythonhosted.org/packages/04/d6/bb5468da53321baeb001f6e4e0d9049eadd175a4a497709939128556e3ec/scipy-1.16.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d85495cef541729a70cdddbbf3e6b903421bc1af3e8e3a9a72a06751f33b7c39", size = 38129275, upload-time = "2025-07-27T16:27:23.873Z" }, + { url = "https://files.pythonhosted.org/packages/c4/94/994369978509f227cba7dfb9e623254d0d5559506fe994aef4bea3ed469c/scipy-1.16.1-cp311-cp311-win_amd64.whl", hash = "sha256:226652fca853008119c03a8ce71ffe1b3f6d2844cc1686e8f9806edafae68596", size = 38644572, upload-time = "2025-07-27T16:27:32.637Z" }, + { url = "https://files.pythonhosted.org/packages/f8/d9/ec4864f5896232133f51382b54a08de91a9d1af7a76dfa372894026dfee2/scipy-1.16.1-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:81b433bbeaf35728dad619afc002db9b189e45eebe2cd676effe1fb93fef2b9c", size = 36575194, upload-time = "2025-07-27T16:27:41.321Z" }, + { url = "https://files.pythonhosted.org/packages/5c/6d/40e81ecfb688e9d25d34a847dca361982a6addf8e31f0957b1a54fbfa994/scipy-1.16.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:886cc81fdb4c6903a3bb0464047c25a6d1016fef77bb97949817d0c0d79f9e04", size = 28594590, upload-time = "2025-07-27T16:27:49.204Z" }, + { url = "https://files.pythonhosted.org/packages/0e/37/9f65178edfcc629377ce9a64fc09baebea18c80a9e57ae09a52edf84880b/scipy-1.16.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:15240c3aac087a522b4eaedb09f0ad061753c5eebf1ea430859e5bf8640d5919", size = 20866458, upload-time = "2025-07-27T16:27:54.98Z" }, + { url = "https://files.pythonhosted.org/packages/2c/7b/749a66766871ea4cb1d1ea10f27004db63023074c22abed51f22f09770e0/scipy-1.16.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:65f81a25805f3659b48126b5053d9e823d3215e4a63730b5e1671852a1705921", size = 23539318, upload-time = "2025-07-27T16:28:01.604Z" }, + { url = "https://files.pythonhosted.org/packages/c4/db/8d4afec60eb833a666434d4541a3151eedbf2494ea6d4d468cbe877f00cd/scipy-1.16.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6c62eea7f607f122069b9bad3f99489ddca1a5173bef8a0c75555d7488b6f725", size = 33292899, upload-time = "2025-07-27T16:28:09.147Z" }, + { url = "https://files.pythonhosted.org/packages/51/1e/79023ca3bbb13a015d7d2757ecca3b81293c663694c35d6541b4dca53e98/scipy-1.16.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f965bbf3235b01c776115ab18f092a95aa74c271a52577bcb0563e85738fd618", size = 35162637, upload-time = "2025-07-27T16:28:17.535Z" }, + { url = "https://files.pythonhosted.org/packages/b6/49/0648665f9c29fdaca4c679182eb972935b3b4f5ace41d323c32352f29816/scipy-1.16.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f006e323874ffd0b0b816d8c6a8e7f9a73d55ab3b8c3f72b752b226d0e3ac83d", size = 35490507, upload-time = "2025-07-27T16:28:25.705Z" }, + { url = "https://files.pythonhosted.org/packages/62/8f/66cbb9d6bbb18d8c658f774904f42a92078707a7c71e5347e8bf2f52bb89/scipy-1.16.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e8fd15fc5085ab4cca74cb91fe0a4263b1f32e4420761ddae531ad60934c2119", size = 37923998, upload-time = "2025-07-27T16:28:34.339Z" }, + { url = "https://files.pythonhosted.org/packages/14/c3/61f273ae550fbf1667675701112e380881905e28448c080b23b5a181df7c/scipy-1.16.1-cp312-cp312-win_amd64.whl", hash = "sha256:f7b8013c6c066609577d910d1a2a077021727af07b6fab0ee22c2f901f22352a", size = 38508060, upload-time = "2025-07-27T16:28:43.242Z" }, + { url = "https://files.pythonhosted.org/packages/93/0b/b5c99382b839854a71ca9482c684e3472badc62620287cbbdab499b75ce6/scipy-1.16.1-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:5451606823a5e73dfa621a89948096c6528e2896e40b39248295d3a0138d594f", size = 36533717, upload-time = "2025-07-27T16:28:51.706Z" }, + { url = "https://files.pythonhosted.org/packages/eb/e5/69ab2771062c91e23e07c12e7d5033a6b9b80b0903ee709c3c36b3eb520c/scipy-1.16.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:89728678c5ca5abd610aee148c199ac1afb16e19844401ca97d43dc548a354eb", size = 28570009, upload-time = "2025-07-27T16:28:57.017Z" }, + { url = "https://files.pythonhosted.org/packages/f4/69/bd75dbfdd3cf524f4d753484d723594aed62cfaac510123e91a6686d520b/scipy-1.16.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e756d688cb03fd07de0fffad475649b03cb89bee696c98ce508b17c11a03f95c", size = 20841942, upload-time = "2025-07-27T16:29:01.152Z" }, + { url = "https://files.pythonhosted.org/packages/ea/74/add181c87663f178ba7d6144b370243a87af8476664d5435e57d599e6874/scipy-1.16.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5aa2687b9935da3ed89c5dbed5234576589dd28d0bf7cd237501ccfbdf1ad608", size = 23498507, upload-time = "2025-07-27T16:29:05.202Z" }, + { url = "https://files.pythonhosted.org/packages/1d/74/ece2e582a0d9550cee33e2e416cc96737dce423a994d12bbe59716f47ff1/scipy-1.16.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0851f6a1e537fe9399f35986897e395a1aa61c574b178c0d456be5b1a0f5ca1f", size = 33286040, upload-time = "2025-07-27T16:29:10.201Z" }, + { url = "https://files.pythonhosted.org/packages/e4/82/08e4076df538fb56caa1d489588d880ec7c52d8273a606bb54d660528f7c/scipy-1.16.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fedc2cbd1baed37474b1924c331b97bdff611d762c196fac1a9b71e67b813b1b", size = 35176096, upload-time = "2025-07-27T16:29:17.091Z" }, + { url = "https://files.pythonhosted.org/packages/fa/79/cd710aab8c921375711a8321c6be696e705a120e3011a643efbbcdeeabcc/scipy-1.16.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2ef500e72f9623a6735769e4b93e9dcb158d40752cdbb077f305487e3e2d1f45", size = 35490328, upload-time = "2025-07-27T16:29:22.928Z" }, + { url = "https://files.pythonhosted.org/packages/71/73/e9cc3d35ee4526d784520d4494a3e1ca969b071fb5ae5910c036a375ceec/scipy-1.16.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:978d8311674b05a8f7ff2ea6c6bce5d8b45a0cb09d4c5793e0318f448613ea65", size = 37939921, upload-time = "2025-07-27T16:29:29.108Z" }, + { url = "https://files.pythonhosted.org/packages/21/12/c0efd2941f01940119b5305c375ae5c0fcb7ec193f806bd8f158b73a1782/scipy-1.16.1-cp313-cp313-win_amd64.whl", hash = "sha256:81929ed0fa7a5713fcdd8b2e6f73697d3b4c4816d090dd34ff937c20fa90e8ab", size = 38479462, upload-time = "2025-07-27T16:30:24.078Z" }, + { url = "https://files.pythonhosted.org/packages/7a/19/c3d08b675260046a991040e1ea5d65f91f40c7df1045fffff412dcfc6765/scipy-1.16.1-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:bcc12db731858abda693cecdb3bdc9e6d4bd200213f49d224fe22df82687bdd6", size = 36938832, upload-time = "2025-07-27T16:29:35.057Z" }, + { url = "https://files.pythonhosted.org/packages/81/f2/ce53db652c033a414a5b34598dba6b95f3d38153a2417c5a3883da429029/scipy-1.16.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:744d977daa4becb9fc59135e75c069f8d301a87d64f88f1e602a9ecf51e77b27", size = 29093084, upload-time = "2025-07-27T16:29:40.201Z" }, + { url = "https://files.pythonhosted.org/packages/a9/ae/7a10ff04a7dc15f9057d05b33737ade244e4bd195caa3f7cc04d77b9e214/scipy-1.16.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:dc54f76ac18073bcecffb98d93f03ed6b81a92ef91b5d3b135dcc81d55a724c7", size = 21365098, upload-time = "2025-07-27T16:29:44.295Z" }, + { url = "https://files.pythonhosted.org/packages/36/ac/029ff710959932ad3c2a98721b20b405f05f752f07344622fd61a47c5197/scipy-1.16.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:367d567ee9fc1e9e2047d31f39d9d6a7a04e0710c86e701e053f237d14a9b4f6", size = 23896858, upload-time = "2025-07-27T16:29:48.784Z" }, + { url = "https://files.pythonhosted.org/packages/71/13/d1ef77b6bd7898720e1f0b6b3743cb945f6c3cafa7718eaac8841035ab60/scipy-1.16.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4cf5785e44e19dcd32a0e4807555e1e9a9b8d475c6afff3d21c3c543a6aa84f4", size = 33438311, upload-time = "2025-07-27T16:29:54.164Z" }, + { url = "https://files.pythonhosted.org/packages/2d/e0/e64a6821ffbb00b4c5b05169f1c1fddb4800e9307efe3db3788995a82a2c/scipy-1.16.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3d0b80fb26d3e13a794c71d4b837e2a589d839fd574a6bbb4ee1288c213ad4a3", size = 35279542, upload-time = "2025-07-27T16:30:00.249Z" }, + { url = "https://files.pythonhosted.org/packages/57/59/0dc3c8b43e118f1e4ee2b798dcc96ac21bb20014e5f1f7a8e85cc0653bdb/scipy-1.16.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8503517c44c18d1030d666cb70aaac1cc8913608816e06742498833b128488b7", size = 35667665, upload-time = "2025-07-27T16:30:05.916Z" }, + { url = "https://files.pythonhosted.org/packages/45/5f/844ee26e34e2f3f9f8febb9343748e72daeaec64fe0c70e9bf1ff84ec955/scipy-1.16.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:30cc4bb81c41831ecfd6dc450baf48ffd80ef5aed0f5cf3ea775740e80f16ecc", size = 38045210, upload-time = "2025-07-27T16:30:11.655Z" }, + { url = "https://files.pythonhosted.org/packages/8d/d7/210f2b45290f444f1de64bc7353aa598ece9f0e90c384b4a156f9b1a5063/scipy-1.16.1-cp313-cp313t-win_amd64.whl", hash = "sha256:c24fa02f7ed23ae514460a22c57eca8f530dbfa50b1cfdbf4f37c05b5309cc39", size = 38593661, upload-time = "2025-07-27T16:30:17.825Z" }, +] + +[[package]] +name = "scipy-stubs" +version = "1.16.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "optype", extra = ["numpy"] }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ab/7e/978c7cad40405cb927d065c31bfaefbc09b4f6cf1ce97e4af6625b1935ab/scipy_stubs-1.16.1.1.tar.gz", hash = "sha256:5b36fdcc1a66cc530c08917fa7c7499ec7a607487735419c677742dcf25803fb", size = 347578, upload-time = "2025-08-21T00:57:31.306Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fa/1b/8c2b4f0e957ad23d30419c01e9ef874284c09ceb942daf3a6546ffd51e6e/scipy_stubs-1.16.1.1-py3-none-any.whl", hash = "sha256:8c3e98a5a7def79570cbd6e2f4316da570d48b7945a630ac016b199d12c31918", size = 553763, upload-time = "2025-08-21T00:57:27.649Z" }, ] [[package]] @@ -2565,72 +3081,120 @@ dependencies = [ { name = "numpy" }, { name = "pandas" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/86/59/a451d7420a77ab0b98f7affa3a1d78a313d2f7281a57afb1a34bae8ab412/seaborn-0.13.2.tar.gz", hash = "sha256:93e60a40988f4d65e9f4885df477e2fdaff6b73a9ded434c1ab356dd57eefff7", size = 1457696 } +sdist = { url = "https://files.pythonhosted.org/packages/86/59/a451d7420a77ab0b98f7affa3a1d78a313d2f7281a57afb1a34bae8ab412/seaborn-0.13.2.tar.gz", hash = "sha256:93e60a40988f4d65e9f4885df477e2fdaff6b73a9ded434c1ab356dd57eefff7", size = 1457696, upload-time = "2024-01-25T13:21:52.551Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/83/11/00d3c3dfc25ad54e731d91449895a79e4bf2384dc3ac01809010ba88f6d5/seaborn-0.13.2-py3-none-any.whl", hash = "sha256:636f8336facf092165e27924f223d3c62ca560b1f2bb5dff7ab7fad265361987", size = 294914 }, + { url = "https://files.pythonhosted.org/packages/83/11/00d3c3dfc25ad54e731d91449895a79e4bf2384dc3ac01809010ba88f6d5/seaborn-0.13.2-py3-none-any.whl", hash = "sha256:636f8336facf092165e27924f223d3c62ca560b1f2bb5dff7ab7fad265361987", size = 294914, upload-time = "2024-01-25T13:21:49.598Z" }, ] [[package]] name = "send2trash" version = "1.8.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fd/3a/aec9b02217bb79b87bbc1a21bc6abc51e3d5dcf65c30487ac96c0908c722/Send2Trash-1.8.3.tar.gz", hash = "sha256:b18e7a3966d99871aefeb00cfbcfdced55ce4871194810fc71f4aa484b953abf", size = 17394 } +sdist = { url = "https://files.pythonhosted.org/packages/fd/3a/aec9b02217bb79b87bbc1a21bc6abc51e3d5dcf65c30487ac96c0908c722/Send2Trash-1.8.3.tar.gz", hash = "sha256:b18e7a3966d99871aefeb00cfbcfdced55ce4871194810fc71f4aa484b953abf", size = 17394, upload-time = "2024-04-07T00:01:09.267Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/40/b0/4562db6223154aa4e22f939003cb92514c79f3d4dccca3444253fd17f902/Send2Trash-1.8.3-py3-none-any.whl", hash = "sha256:0c31227e0bd08961c7665474a3d1ef7193929fedda4233843689baa056be46c9", size = 18072 }, + { url = "https://files.pythonhosted.org/packages/40/b0/4562db6223154aa4e22f939003cb92514c79f3d4dccca3444253fd17f902/Send2Trash-1.8.3-py3-none-any.whl", hash = "sha256:0c31227e0bd08961c7665474a3d1ef7193929fedda4233843689baa056be46c9", size = 18072, upload-time = "2024-04-07T00:01:07.438Z" }, ] [[package]] -name = "session-info" -version = "1.0.0" +name = "session-info2" +version = "0.2.1" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "stdlib-list" }, +sdist = { url = "https://files.pythonhosted.org/packages/82/e6/29acd849dbc37ad80e251834e2759f0acf1ae33864781455aa1d5b051ce6/session_info2-0.2.1.tar.gz", hash = "sha256:f2aa4ae95db7f40239608217d7c077b6a51bc3d897792010ea3794ea799bd69c", size = 23257, upload-time = "2025-08-20T15:43:00.938Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/a2/8575bc8036ee4f96043cd6b4433b3adc120aa365a6b7aef19f564c99cbb7/session_info2-0.2.1-py3-none-any.whl", hash = "sha256:2554f974441fe5a230d45ef5389cfaf663af7ff41520b488a633c03743f34658", size = 16066, upload-time = "2025-08-20T15:42:59.535Z" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/94/e4/ea615bb8185a298b21df1ac52a4a5db4e3351823a218f47ef3f883def88c/session_info-1.0.0.tar.gz", hash = "sha256:3cda5e03cca703f32ae2eadbd6bd80b6c21442cfb60e412c21cb8ad6d5cbb6b7", size = 24345 } [[package]] name = "setuptools" -version = "59.8.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ef/75/2bc7bef4d668f9caa9c6ed3f3187989922765403198243040d08d2a52725/setuptools-59.8.0.tar.gz", hash = "sha256:09980778aa734c3037a47997f28d6db5ab18bdf2af0e49f719bfc53967fd2e82", size = 2282358 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8d/25/88b377b99ffb4ad0fc44ff5735fd6be605b2183f743d1ff5c10b7790cea5/setuptools-59.8.0-py3-none-any.whl", hash = "sha256:608a7885b664342ae9fafc43840b29d219c5a578876f6f7e00c4e2612160587f", size = 952779 }, +version = "80.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958, upload-time = "2025-05-27T00:56:51.443Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload-time = "2025-05-27T00:56:49.664Z" }, +] + +[[package]] +name = "simplejson" +version = "3.20.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/af/92/51b417685abd96b31308b61b9acce7ec50d8e1de8fbc39a7fd4962c60689/simplejson-3.20.1.tar.gz", hash = "sha256:e64139b4ec4f1f24c142ff7dcafe55a22b811a74d86d66560c8815687143037d", size = 85591, upload-time = "2025-02-15T05:18:53.15Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/59/74bc90d1c051bc2432c96b34bd4e8036875ab58b4fcbe4d6a5a76985f853/simplejson-3.20.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:325b8c107253d3217e89d7b50c71015b5b31e2433e6c5bf38967b2f80630a8ca", size = 92132, upload-time = "2025-02-15T05:16:15.743Z" }, + { url = "https://files.pythonhosted.org/packages/71/c7/1970916e0c51794fff89f76da2f632aaf0b259b87753c88a8c409623d3e1/simplejson-3.20.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:88a7baa8211089b9e58d78fbc1b0b322103f3f3d459ff16f03a36cece0d0fcf0", size = 74956, upload-time = "2025-02-15T05:16:17.062Z" }, + { url = "https://files.pythonhosted.org/packages/c8/0d/98cc5909180463f1d75fac7180de62d4cdb4e82c4fef276b9e591979372c/simplejson-3.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:299b1007b8101d50d95bc0db1bf5c38dc372e85b504cf77f596462083ee77e3f", size = 74772, upload-time = "2025-02-15T05:16:19.204Z" }, + { url = "https://files.pythonhosted.org/packages/e1/94/a30a5211a90d67725a3e8fcc1c788189f2ae2ed2b96b63ed15d0b7f5d6bb/simplejson-3.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03ec618ed65caab48e81e3ed29586236a8e57daef792f1f3bb59504a7e98cd10", size = 143575, upload-time = "2025-02-15T05:16:21.337Z" }, + { url = "https://files.pythonhosted.org/packages/ee/08/cdb6821f1058eb5db46d252de69ff7e6c53f05f1bae6368fe20d5b51d37e/simplejson-3.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd2cdead1d3197f0ff43373cf4730213420523ba48697743e135e26f3d179f38", size = 153241, upload-time = "2025-02-15T05:16:22.859Z" }, + { url = "https://files.pythonhosted.org/packages/4c/2d/ca3caeea0bdc5efc5503d5f57a2dfb56804898fb196dfada121323ee0ccb/simplejson-3.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3466d2839fdc83e1af42e07b90bc8ff361c4e8796cd66722a40ba14e458faddd", size = 141500, upload-time = "2025-02-15T05:16:25.068Z" }, + { url = "https://files.pythonhosted.org/packages/e1/33/d3e0779d5c58245e7370c98eb969275af6b7a4a5aec3b97cbf85f09ad328/simplejson-3.20.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d492ed8e92f3a9f9be829205f44b1d0a89af6582f0cf43e0d129fa477b93fe0c", size = 144757, upload-time = "2025-02-15T05:16:28.301Z" }, + { url = "https://files.pythonhosted.org/packages/54/53/2d93128bb55861b2fa36c5944f38da51a0bc6d83e513afc6f7838440dd15/simplejson-3.20.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f924b485537b640dc69434565463fd6fc0c68c65a8c6e01a823dd26c9983cf79", size = 144409, upload-time = "2025-02-15T05:16:29.687Z" }, + { url = "https://files.pythonhosted.org/packages/99/4c/dac310a98f897ad3435b4bdc836d92e78f09e38c5dbf28211ed21dc59fa2/simplejson-3.20.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9e8eacf6a3491bf76ea91a8d46726368a6be0eb94993f60b8583550baae9439e", size = 146082, upload-time = "2025-02-15T05:16:31.064Z" }, + { url = "https://files.pythonhosted.org/packages/ee/22/d7ba958cfed39827335b82656b1c46f89678faecda9a7677b47e87b48ee6/simplejson-3.20.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d34d04bf90b4cea7c22d8b19091633908f14a096caa301b24c2f3d85b5068fb8", size = 154339, upload-time = "2025-02-15T05:16:32.719Z" }, + { url = "https://files.pythonhosted.org/packages/b8/c8/b072b741129406a7086a0799c6f5d13096231bf35fdd87a0cffa789687fc/simplejson-3.20.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:69dd28d4ce38390ea4aaf212902712c0fd1093dc4c1ff67e09687c3c3e15a749", size = 147915, upload-time = "2025-02-15T05:16:34.291Z" }, + { url = "https://files.pythonhosted.org/packages/6c/46/8347e61e9cf3db5342a42f7fd30a81b4f5cf85977f916852d7674a540907/simplejson-3.20.1-cp311-cp311-win32.whl", hash = "sha256:dfe7a9da5fd2a3499436cd350f31539e0a6ded5da6b5b3d422df016444d65e43", size = 73972, upload-time = "2025-02-15T05:16:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/01/85/b52f24859237b4e9d523d5655796d911ba3d46e242eb1959c45b6af5aedd/simplejson-3.20.1-cp311-cp311-win_amd64.whl", hash = "sha256:896a6c04d7861d507d800da7642479c3547060bf97419d9ef73d98ced8258766", size = 75595, upload-time = "2025-02-15T05:16:36.957Z" }, + { url = "https://files.pythonhosted.org/packages/8d/eb/34c16a1ac9ba265d024dc977ad84e1659d931c0a700967c3e59a98ed7514/simplejson-3.20.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f31c4a3a7ab18467ee73a27f3e59158255d1520f3aad74315edde7a940f1be23", size = 93100, upload-time = "2025-02-15T05:16:38.801Z" }, + { url = "https://files.pythonhosted.org/packages/41/fc/2c2c007d135894971e6814e7c0806936e5bade28f8db4dd7e2a58b50debd/simplejson-3.20.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:884e6183d16b725e113b83a6fc0230152ab6627d4d36cb05c89c2c5bccfa7bc6", size = 75464, upload-time = "2025-02-15T05:16:40.905Z" }, + { url = "https://files.pythonhosted.org/packages/0f/05/2b5ecb33b776c34bb5cace5de5d7669f9b60e3ca13c113037b2ca86edfbd/simplejson-3.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03d7a426e416fe0d3337115f04164cd9427eb4256e843a6b8751cacf70abc832", size = 75112, upload-time = "2025-02-15T05:16:42.246Z" }, + { url = "https://files.pythonhosted.org/packages/fe/36/1f3609a2792f06cd4b71030485f78e91eb09cfd57bebf3116bf2980a8bac/simplejson-3.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:000602141d0bddfcff60ea6a6e97d5e10c9db6b17fd2d6c66199fa481b6214bb", size = 150182, upload-time = "2025-02-15T05:16:43.557Z" }, + { url = "https://files.pythonhosted.org/packages/2f/b0/053fbda38b8b602a77a4f7829def1b4f316cd8deb5440a6d3ee90790d2a4/simplejson-3.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:af8377a8af78226e82e3a4349efdde59ffa421ae88be67e18cef915e4023a595", size = 158363, upload-time = "2025-02-15T05:16:45.748Z" }, + { url = "https://files.pythonhosted.org/packages/d1/4b/2eb84ae867539a80822e92f9be4a7200dffba609275faf99b24141839110/simplejson-3.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15c7de4c88ab2fbcb8781a3b982ef883696736134e20b1210bca43fb42ff1acf", size = 148415, upload-time = "2025-02-15T05:16:47.861Z" }, + { url = "https://files.pythonhosted.org/packages/e0/bd/400b0bd372a5666addf2540c7358bfc3841b9ce5cdbc5cc4ad2f61627ad8/simplejson-3.20.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:455a882ff3f97d810709f7b620007d4e0aca8da71d06fc5c18ba11daf1c4df49", size = 152213, upload-time = "2025-02-15T05:16:49.25Z" }, + { url = "https://files.pythonhosted.org/packages/50/12/143f447bf6a827ee9472693768dc1a5eb96154f8feb140a88ce6973a3cfa/simplejson-3.20.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:fc0f523ce923e7f38eb67804bc80e0a028c76d7868500aa3f59225574b5d0453", size = 150048, upload-time = "2025-02-15T05:16:51.5Z" }, + { url = "https://files.pythonhosted.org/packages/5e/ea/dd9b3e8e8ed710a66f24a22c16a907c9b539b6f5f45fd8586bd5c231444e/simplejson-3.20.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:76461ec929282dde4a08061071a47281ad939d0202dc4e63cdd135844e162fbc", size = 151668, upload-time = "2025-02-15T05:16:53Z" }, + { url = "https://files.pythonhosted.org/packages/99/af/ee52a8045426a0c5b89d755a5a70cc821815ef3c333b56fbcad33c4435c0/simplejson-3.20.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ab19c2da8c043607bde4d4ef3a6b633e668a7d2e3d56f40a476a74c5ea71949f", size = 158840, upload-time = "2025-02-15T05:16:54.851Z" }, + { url = "https://files.pythonhosted.org/packages/68/db/ab32869acea6b5de7d75fa0dac07a112ded795d41eaa7e66c7813b17be95/simplejson-3.20.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b2578bedaedf6294415197b267d4ef678fea336dd78ee2a6d2f4b028e9d07be3", size = 154212, upload-time = "2025-02-15T05:16:56.318Z" }, + { url = "https://files.pythonhosted.org/packages/fa/7a/e3132d454977d75a3bf9a6d541d730f76462ebf42a96fea2621498166f41/simplejson-3.20.1-cp312-cp312-win32.whl", hash = "sha256:339f407373325a36b7fd744b688ba5bae0666b5d340ec6d98aebc3014bf3d8ea", size = 74101, upload-time = "2025-02-15T05:16:57.746Z" }, + { url = "https://files.pythonhosted.org/packages/bc/5d/4e243e937fa3560107c69f6f7c2eed8589163f5ed14324e864871daa2dd9/simplejson-3.20.1-cp312-cp312-win_amd64.whl", hash = "sha256:627d4486a1ea7edf1f66bb044ace1ce6b4c1698acd1b05353c97ba4864ea2e17", size = 75736, upload-time = "2025-02-15T05:16:59.017Z" }, + { url = "https://files.pythonhosted.org/packages/c4/03/0f453a27877cb5a5fff16a975925f4119102cc8552f52536b9a98ef0431e/simplejson-3.20.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:71e849e7ceb2178344998cbe5ade101f1b329460243c79c27fbfc51c0447a7c3", size = 93109, upload-time = "2025-02-15T05:17:00.377Z" }, + { url = "https://files.pythonhosted.org/packages/74/1f/a729f4026850cabeaff23e134646c3f455e86925d2533463420635ae54de/simplejson-3.20.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b63fdbab29dc3868d6f009a59797cefaba315fd43cd32ddd998ee1da28e50e29", size = 75475, upload-time = "2025-02-15T05:17:02.544Z" }, + { url = "https://files.pythonhosted.org/packages/e2/14/50a2713fee8ff1f8d655b1a14f4a0f1c0c7246768a1b3b3d12964a4ed5aa/simplejson-3.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1190f9a3ce644fd50ec277ac4a98c0517f532cfebdcc4bd975c0979a9f05e1fb", size = 75112, upload-time = "2025-02-15T05:17:03.875Z" }, + { url = "https://files.pythonhosted.org/packages/45/86/ea9835abb646755140e2d482edc9bc1e91997ed19a59fd77ae4c6a0facea/simplejson-3.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1336ba7bcb722ad487cd265701ff0583c0bb6de638364ca947bb84ecc0015d1", size = 150245, upload-time = "2025-02-15T05:17:06.899Z" }, + { url = "https://files.pythonhosted.org/packages/12/b4/53084809faede45da829fe571c65fbda8479d2a5b9c633f46b74124d56f5/simplejson-3.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e975aac6a5acd8b510eba58d5591e10a03e3d16c1cf8a8624ca177491f7230f0", size = 158465, upload-time = "2025-02-15T05:17:08.707Z" }, + { url = "https://files.pythonhosted.org/packages/a9/7d/d56579468d1660b3841e1f21c14490d103e33cf911886b22652d6e9683ec/simplejson-3.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6a6dd11ee282937ad749da6f3b8d87952ad585b26e5edfa10da3ae2536c73078", size = 148514, upload-time = "2025-02-15T05:17:11.323Z" }, + { url = "https://files.pythonhosted.org/packages/19/e3/874b1cca3d3897b486d3afdccc475eb3a09815bf1015b01cf7fcb52a55f0/simplejson-3.20.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab980fcc446ab87ea0879edad41a5c28f2d86020014eb035cf5161e8de4474c6", size = 152262, upload-time = "2025-02-15T05:17:13.543Z" }, + { url = "https://files.pythonhosted.org/packages/32/84/f0fdb3625292d945c2bd13a814584603aebdb38cfbe5fe9be6b46fe598c4/simplejson-3.20.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f5aee2a4cb6b146bd17333ac623610f069f34e8f31d2f4f0c1a2186e50c594f0", size = 150164, upload-time = "2025-02-15T05:17:15.021Z" }, + { url = "https://files.pythonhosted.org/packages/95/51/6d625247224f01eaaeabace9aec75ac5603a42f8ebcce02c486fbda8b428/simplejson-3.20.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:652d8eecbb9a3b6461b21ec7cf11fd0acbab144e45e600c817ecf18e4580b99e", size = 151795, upload-time = "2025-02-15T05:17:16.542Z" }, + { url = "https://files.pythonhosted.org/packages/7f/d9/bb921df6b35be8412f519e58e86d1060fddf3ad401b783e4862e0a74c4c1/simplejson-3.20.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:8c09948f1a486a89251ee3a67c9f8c969b379f6ffff1a6064b41fea3bce0a112", size = 159027, upload-time = "2025-02-15T05:17:18.083Z" }, + { url = "https://files.pythonhosted.org/packages/03/c5/5950605e4ad023a6621cf4c931b29fd3d2a9c1f36be937230bfc83d7271d/simplejson-3.20.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:cbbd7b215ad4fc6f058b5dd4c26ee5c59f72e031dfda3ac183d7968a99e4ca3a", size = 154380, upload-time = "2025-02-15T05:17:20.334Z" }, + { url = "https://files.pythonhosted.org/packages/66/ad/b74149557c5ec1e4e4d55758bda426f5d2ec0123cd01a53ae63b8de51fa3/simplejson-3.20.1-cp313-cp313-win32.whl", hash = "sha256:ae81e482476eaa088ef9d0120ae5345de924f23962c0c1e20abbdff597631f87", size = 74102, upload-time = "2025-02-15T05:17:22.475Z" }, + { url = "https://files.pythonhosted.org/packages/db/a9/25282fdd24493e1022f30b7f5cdf804255c007218b2bfaa655bd7ad34b2d/simplejson-3.20.1-cp313-cp313-win_amd64.whl", hash = "sha256:1b9fd15853b90aec3b1739f4471efbf1ac05066a2c7041bf8db821bb73cd2ddc", size = 75736, upload-time = "2025-02-15T05:17:24.122Z" }, + { url = "https://files.pythonhosted.org/packages/4b/30/00f02a0a921556dd5a6db1ef2926a1bc7a8bbbfb1c49cfed68a275b8ab2b/simplejson-3.20.1-py3-none-any.whl", hash = "sha256:8a6c1bbac39fa4a79f83cbf1df6ccd8ff7069582a9fd8db1e52cea073bc2c697", size = 57121, upload-time = "2025-02-15T05:18:51.243Z" }, ] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", size = 34041 } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", size = 11053 }, + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, ] [[package]] name = "sniffio" version = "1.3.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, ] [[package]] name = "sortedcontainers" version = "2.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/c4/ba2f8066cceb6f23394729afe52f3bf7adec04bf9ed2c820b39e19299111/sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88", size = 30594 } +sdist = { url = "https://files.pythonhosted.org/packages/e8/c4/ba2f8066cceb6f23394729afe52f3bf7adec04bf9ed2c820b39e19299111/sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88", size = 30594, upload-time = "2021-05-16T22:03:42.897Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575 }, + { url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575, upload-time = "2021-05-16T22:03:41.177Z" }, ] [[package]] name = "soupsieve" -version = "2.6" +version = "2.8" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d7/ce/fbaeed4f9fb8b2daa961f90591662df6a86c1abf25c548329a86920aedfb/soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb", size = 101569 } +sdist = { url = "https://files.pythonhosted.org/packages/6d/e6/21ccce3262dd4889aa3332e5a119a3491a95e8f60939870a3a035aabac0d/soupsieve-2.8.tar.gz", hash = "sha256:e2dd4a40a628cb5f28f6d4b0db8800b8f581b65bb380b97de22ba5ca8d72572f", size = 103472, upload-time = "2025-08-27T15:39:51.78Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/c2/fe97d779f3ef3b15f05c94a2f1e3d21732574ed441687474db9d342a7315/soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9", size = 36186 }, + { url = "https://files.pythonhosted.org/packages/14/a0/bb38d3b76b8cae341dad93a2dd83ab7462e6dbcdd84d43f54ee60a8dc167/soupsieve-2.8-py3-none-any.whl", hash = "sha256:0cc76456a30e20f5d7f2e14a98a4ae2ee4e5abdc7c5ea0aafe795f344bc7984c", size = 36679, upload-time = "2025-08-27T15:39:50.179Z" }, ] [[package]] @@ -2642,14 +3206,14 @@ dependencies = [ { name = "executing" }, { name = "pure-eval" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", size = 44707 } +sdist = { url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", size = 44707, upload-time = "2023-09-30T13:58:05.479Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521 }, + { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521, upload-time = "2023-09-30T13:58:03.53Z" }, ] [[package]] name = "statsmodels" -version = "0.14.4" +version = "0.14.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, @@ -2658,88 +3222,76 @@ dependencies = [ { name = "patsy" }, { name = "scipy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1f/3b/963a015dd8ea17e10c7b0e2f14d7c4daec903baf60a017e756b57953a4bf/statsmodels-0.14.4.tar.gz", hash = "sha256:5d69e0f39060dc72c067f9bb6e8033b6dccdb0bae101d76a7ef0bcc94e898b67", size = 20354802 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/af/2c/23bf5ad9e8a77c0c8d9750512bff89e32154dea91998114118e0e147ae67/statsmodels-0.14.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7a62f1fc9086e4b7ee789a6f66b3c0fc82dd8de1edda1522d30901a0aa45e42b", size = 10216574 }, - { url = "https://files.pythonhosted.org/packages/ba/a5/2f09ab918296e534ea5d132e90efac51ae12ff15992d77539bbfca1158fa/statsmodels-0.14.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:46ac7ddefac0c9b7b607eed1d47d11e26fe92a1bc1f4d9af48aeed4e21e87981", size = 9912430 }, - { url = "https://files.pythonhosted.org/packages/93/6a/b86f8c9b799dc93e5b4a3267eb809843e6328e34248a53496b96f50d732e/statsmodels-0.14.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a337b731aa365d09bb0eab6da81446c04fde6c31976b1d8e3d3a911f0f1e07b", size = 10444673 }, - { url = "https://files.pythonhosted.org/packages/78/44/d72c634211797ed07dd8c63ced4ae11debd7a40b24ee80e79346a526194f/statsmodels-0.14.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:631bb52159117c5da42ba94bd94859276b68cab25dc4cac86475bc24671143bc", size = 10811248 }, - { url = "https://files.pythonhosted.org/packages/35/64/df81426924fcc48a0402534efa96cde13275629ae52f123189d16c4b75ff/statsmodels-0.14.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3bb2e580d382545a65f298589809af29daeb15f9da2eb252af8f79693e618abc", size = 10946447 }, - { url = "https://files.pythonhosted.org/packages/5c/f9/205130cceeda0eebd5a1a58c04e060c2f87a1d63cbbe37a9caa0fcb50c68/statsmodels-0.14.4-cp310-cp310-win_amd64.whl", hash = "sha256:9729642884147ee9db67b5a06a355890663d21f76ed608a56ac2ad98b94d201a", size = 9845796 }, - { url = "https://files.pythonhosted.org/packages/48/88/326f5f689e69d9c47a68a22ffdd20a6ea6410b53918f9a8e63380dfc181c/statsmodels-0.14.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5ed7e118e6e3e02d6723a079b8c97eaadeed943fa1f7f619f7148dfc7862670f", size = 10221032 }, - { url = "https://files.pythonhosted.org/packages/07/0b/9a0818be42f6689ebdc7a2277ea984d6299f0809d0e0277128df4f7dc606/statsmodels-0.14.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f5f537f7d000de4a1708c63400755152b862cd4926bb81a86568e347c19c364b", size = 9912219 }, - { url = "https://files.pythonhosted.org/packages/b1/f2/91c70a3b4a3e416f76ead61b04c87bc60080d634d7fa2ab893976bdd86fa/statsmodels-0.14.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa74aaa26eaa5012b0a01deeaa8a777595d0835d3d6c7175f2ac65435a7324d2", size = 10424053 }, - { url = "https://files.pythonhosted.org/packages/9d/4f/a96e682f82b675e4a6f3de8ad990587d8b1fde500a630a2aabcaabee11d8/statsmodels-0.14.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e332c2d9b806083d1797231280602340c5c913f90d4caa0213a6a54679ce9331", size = 10752529 }, - { url = "https://files.pythonhosted.org/packages/4b/c6/47549345d32da1530a819a3699f6f34f9f70733a245eeb29f5e05e53f362/statsmodels-0.14.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d9c8fa28dfd75753d9cf62769ba1fecd7e73a0be187f35cc6f54076f98aa3f3f", size = 10959003 }, - { url = "https://files.pythonhosted.org/packages/4b/e4/f9e96896278308e17dfd4f60a84826c48117674c980234ee38f59ab28a12/statsmodels-0.14.4-cp311-cp311-win_amd64.whl", hash = "sha256:a6087ecb0714f7c59eb24c22781491e6f1cfffb660b4740e167625ca4f052056", size = 9853281 }, - { url = "https://files.pythonhosted.org/packages/f5/99/654fd41a9024643ee70b239e5ebc987bf98ce9fc2693bd550bee58136564/statsmodels-0.14.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5221dba7424cf4f2561b22e9081de85f5bb871228581124a0d1b572708545199", size = 10220508 }, - { url = "https://files.pythonhosted.org/packages/67/d8/ac30cf4cf97adaa48548be57e7cf02e894f31b45fd55bf9213358d9781c9/statsmodels-0.14.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:17672b30c6b98afe2b095591e32d1d66d4372f2651428e433f16a3667f19eabb", size = 9912317 }, - { url = "https://files.pythonhosted.org/packages/e0/77/2440d551eaf27f9c1d3650e13b3821a35ad5b21d3a19f62fb302af9203e8/statsmodels-0.14.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab5e6312213b8cfb9dca93dd46a0f4dccb856541f91d3306227c3d92f7659245", size = 10301662 }, - { url = "https://files.pythonhosted.org/packages/fa/e1/60a652f18996a40a7410aeb7eb476c18da8a39792c7effe67f06883e9852/statsmodels-0.14.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4bbb150620b53133d6cd1c5d14c28a4f85701e6c781d9b689b53681effaa655f", size = 10741763 }, - { url = "https://files.pythonhosted.org/packages/81/0c/2453eec3ac25e300847d9ed97f41156de145e507391ecb5ac989e111e525/statsmodels-0.14.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bb695c2025d122a101c2aca66d2b78813c321b60d3a7c86bb8ec4467bb53b0f9", size = 10879534 }, - { url = "https://files.pythonhosted.org/packages/59/9a/e466a1b887a1441141e52dbcc98152f013d85076576da6eed2357f2016ae/statsmodels-0.14.4-cp312-cp312-win_amd64.whl", hash = "sha256:7f7917a51766b4e074da283c507a25048ad29a18e527207883d73535e0dc6184", size = 9823866 }, -] - -[[package]] -name = "stdlib-list" -version = "0.11.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5d/04/6b37a71e92ddca16b190b7df62494ac4779d58ced4787f73584eb32c8f03/stdlib_list-0.11.0.tar.gz", hash = "sha256:b74a7b643a77a12637e907f3f62f0ab9f67300bce4014f6b2d3c8b4c8fd63c66", size = 60335 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/16/fe/e07300c027a868d32d8ed7a425503401e91a03ff90e7ca525c115c634ffb/stdlib_list-0.11.0-py3-none-any.whl", hash = "sha256:8bf8decfffaaf273d4cfeb5bd852b910a00dec1037dcf163576803622bccf597", size = 83617 }, +sdist = { url = "https://files.pythonhosted.org/packages/64/cc/8c1bf59bf8203dea1bf2ea811cfe667d7bcc6909c83d8afb02b08e30f50b/statsmodels-0.14.5.tar.gz", hash = "sha256:de260e58cccfd2ceddf835b55a357233d6ca853a1aa4f90f7553a52cc71c6ddf", size = 20525016, upload-time = "2025-07-07T12:14:23.195Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/30/fd49902b30416b828de763e161c0d6e2cc04d119ae4fbdd3f3b43dc8f1be/statsmodels-0.14.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4b7091a8442076c708c926de3603653a160955e80a2b6d931475b7bb8ddc02e5", size = 10053330, upload-time = "2025-07-07T12:07:39.689Z" }, + { url = "https://files.pythonhosted.org/packages/ca/c1/2654541ff6f5790d01d1e5ba36405fde873f4a854f473e90b4fe56b37333/statsmodels-0.14.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:128872be8f3208f4446d91ea9e4261823902fc7997fee7e1a983eb62fd3b7c6e", size = 9735555, upload-time = "2025-07-07T12:13:28.935Z" }, + { url = "https://files.pythonhosted.org/packages/ce/da/6ebb64d0db4e86c0d2d9cde89e03247702da0ab191789f7813d4f9a348da/statsmodels-0.14.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f2ad5aee04ae7196c429df2174df232c057e478c5fa63193d01c8ec9aae04d31", size = 10307522, upload-time = "2025-07-07T14:22:32.853Z" }, + { url = "https://files.pythonhosted.org/packages/67/49/ac803ca093ec3845184a752a91cd84511245e1f97103b15cfe32794a3bb0/statsmodels-0.14.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f402fc793458dd6d96e099acb44cd1de1428565bf7ef3030878a8daff091f08a", size = 10474665, upload-time = "2025-07-07T14:22:46.011Z" }, + { url = "https://files.pythonhosted.org/packages/f0/c8/ae82feb00582f4814fac5d2cb3ec32f93866b413cf5878b2fe93688ec63c/statsmodels-0.14.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:26c028832730aebfbfd4e7501694e1f9ad31ec8536e776716673f4e7afd4059a", size = 10713120, upload-time = "2025-07-07T14:23:00.067Z" }, + { url = "https://files.pythonhosted.org/packages/05/ac/4276459ea71aa46e2967ea283fc88ee5631c11f29a06787e16cf4aece1b8/statsmodels-0.14.5-cp311-cp311-win_amd64.whl", hash = "sha256:ec56f771d9529cdc17ed2fb2a950d100b6e83a7c5372aae8ac5bb065c474b856", size = 9640980, upload-time = "2025-07-07T12:05:33.085Z" }, + { url = "https://files.pythonhosted.org/packages/5f/a5/fcc4f5f16355660ce7a1742e28a43e3a9391b492fc4ff29fdd6893e81c05/statsmodels-0.14.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:37e7364a39f9aa3b51d15a208c2868b90aadb8412f868530f5cba9197cb00eaa", size = 10042891, upload-time = "2025-07-07T12:13:41.671Z" }, + { url = "https://files.pythonhosted.org/packages/1c/6f/db0cf5efa48277ac6218d9b981c8fd5e63c4c43e0d9d65015fdc38eed0ef/statsmodels-0.14.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4263d7f4d0f1d5ac6eb4db22e1ee34264a14d634b9332c975c9d9109b6b46e12", size = 9698912, upload-time = "2025-07-07T12:07:54.674Z" }, + { url = "https://files.pythonhosted.org/packages/4a/93/4ddc3bc4a59c51e6a57c49df1b889882c40d9e141e855b3517f6a8de3232/statsmodels-0.14.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:86224f6e36f38486e471e75759d241fe2912d8bc25ab157d54ee074c6aedbf45", size = 10237801, upload-time = "2025-07-07T14:23:12.593Z" }, + { url = "https://files.pythonhosted.org/packages/66/de/dc6bf2f6e8c8eb4c5815560ebdbdf2d69a767bc0f65fde34bc086cf5b36d/statsmodels-0.14.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c3dd760a6fa80cd5e0371685c697bb9c2c0e6e1f394d975e596a1e6d0bbb9372", size = 10424154, upload-time = "2025-07-07T14:23:25.365Z" }, + { url = "https://files.pythonhosted.org/packages/16/4f/2d5a8d14bebdf2b03b3ea89b8c6a2c837bb406ba5b7a41add8bd303bce29/statsmodels-0.14.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6264fb00e02f858b86bd01ef2dc05055a71d4a0cc7551b9976b07b0f0e6cf24f", size = 10652915, upload-time = "2025-07-07T14:23:39.337Z" }, + { url = "https://files.pythonhosted.org/packages/df/4c/2feda3a9f0e17444a84ba5398ada6a4d2e1b8f832760048f04e2b8ea0c41/statsmodels-0.14.5-cp312-cp312-win_amd64.whl", hash = "sha256:b2ed065bfbaf8bb214c7201656df840457c2c8c65e1689e3eb09dc7440f9c61c", size = 9611236, upload-time = "2025-07-07T12:08:06.794Z" }, + { url = "https://files.pythonhosted.org/packages/84/fd/4c374108cf108b3130240a5b45847a61f70ddf973429044a81a05189b046/statsmodels-0.14.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:906263134dd1a640e55ecb01fda4a9be7b9e08558dba9e4c4943a486fdb0c9c8", size = 10013958, upload-time = "2025-07-07T14:35:01.04Z" }, + { url = "https://files.pythonhosted.org/packages/5a/36/bf3d7f0e36acd3ba9ec0babd79ace25506b6872780cbd710fb7cd31f0fa2/statsmodels-0.14.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9118f76344f77cffbb3a9cbcff8682b325be5eed54a4b3253e09da77a74263d3", size = 9674243, upload-time = "2025-07-07T12:08:22.571Z" }, + { url = "https://files.pythonhosted.org/packages/90/ce/a55a6f37b5277683ceccd965a5828b24672bbc427db6b3969ae0b0fc29fb/statsmodels-0.14.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9dc4ee159070557c9a6c000625d85f653de437772fe7086857cff68f501afe45", size = 10219521, upload-time = "2025-07-07T14:23:52.646Z" }, + { url = "https://files.pythonhosted.org/packages/1e/48/973da1ee8bc0743519759e74c3615b39acdc3faf00e0a0710f8c856d8c9d/statsmodels-0.14.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a085d47c8ef5387279a991633883d0e700de2b0acc812d7032d165888627bef", size = 10453538, upload-time = "2025-07-07T14:24:06.959Z" }, + { url = "https://files.pythonhosted.org/packages/c7/d6/18903fb707afd31cf1edaec5201964dbdacb2bfae9a22558274647a7c88f/statsmodels-0.14.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9f866b2ebb2904b47c342d00def83c526ef2eb1df6a9a3c94ba5fe63d0005aec", size = 10681584, upload-time = "2025-07-07T14:24:21.038Z" }, + { url = "https://files.pythonhosted.org/packages/44/d6/80df1bbbfcdc50bff4152f43274420fa9856d56e234d160d6206eb1f5827/statsmodels-0.14.5-cp313-cp313-win_amd64.whl", hash = "sha256:2a06bca03b7a492f88c8106103ab75f1a5ced25de90103a89f3a287518017939", size = 9604641, upload-time = "2025-07-07T12:08:36.23Z" }, ] [[package]] name = "swiglpk" -version = "5.0.10" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b7/c3/b635185e6af163af1b6ad786cc5afc6b5926405581c6ddd02c6f93f8a8d3/swiglpk-5.0.10.tar.gz", hash = "sha256:57ac34ad334da95dd168114bfdb50ae10a2a6a3ddef21e4941f46fe430c5a7e1", size = 37559 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/02/01/36a8233149d2500b06a90cb22165bb408499bcd1e8b6129f424304b87055/swiglpk-5.0.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:841e87ac08dc7497a3cc738fce188d15140fa800d101c64b1bb8e8fd555c32ae", size = 786698 }, - { url = "https://files.pythonhosted.org/packages/b2/eb/fd1315b4e87b3c1311f9c390a770e7a605113095924f8bb2a11af74c6061/swiglpk-5.0.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6e22baa37630f5cdc0c634d7046eeb4a31b53914611f4a5bdd1bf53f336c21f2", size = 743174 }, - { url = "https://files.pythonhosted.org/packages/5d/1b/cf75972ac1be75d28d58cd12672a5d64fc08eb58476b1b0a8c9a46f7be19/swiglpk-5.0.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:193bec2c50844024155477bd72a3fd7ef12044578f03b8afd7bbc4c33ca05fd9", size = 2225273 }, - { url = "https://files.pythonhosted.org/packages/d6/98/a5150c8c47e0ce2fac881ef8f2f8f135300021f5db06150787f682a0ca2d/swiglpk-5.0.10-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb54cb336c84cf0d5c32452a59ec404439707aad0cce50a7ae8c3056f8f2185e", size = 2093267 }, - { url = "https://files.pythonhosted.org/packages/f8/f0/d3a5f73939054c60f185781276fb5c590ed7635120eef79bd298255bc14b/swiglpk-5.0.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16750aed2d9dc76c51aa285648d754bec4fa9b6aec31f1e1313b95172078edfe", size = 2300804 }, - { url = "https://files.pythonhosted.org/packages/fe/05/f09ff4205039da10c0a9af406621620cf4ea900dec1c3fb85e9d57fe119c/swiglpk-5.0.10-cp310-cp310-win32.whl", hash = "sha256:9741e58948fd82f2a6afe067d490152c4bb06dedf221a737d506064f38379ef6", size = 463724 }, - { url = "https://files.pythonhosted.org/packages/5e/1e/5291ce3317d8b20c924f17f722cecfa3bd92e5c59cf818f86cb7d4ade264/swiglpk-5.0.10-cp310-cp310-win_amd64.whl", hash = "sha256:c325dc74d7ae1c15f9e9fbc3eac032ecfecad483591afd4c0046050f51640328", size = 573105 }, - { url = "https://files.pythonhosted.org/packages/c9/97/d580c6054bc4d59ca7f9138f65a9c147a73d4c4477030d968dc7c4c635d1/swiglpk-5.0.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b29876e77c9e76a9cea411cb3d34a8b52f1de9cf5909caa88293a2303012eb23", size = 786740 }, - { url = "https://files.pythonhosted.org/packages/37/81/5ceee713a044e6ee247033707d0e5f4c7a2b4c80ac2e6bc19eb3085ebf4d/swiglpk-5.0.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:41df9c17cee06ac864acdb0a7f16d848dcc6bcdbb982950893f06cc97b148470", size = 743174 }, - { url = "https://files.pythonhosted.org/packages/e3/09/fbb262e1ce6ce7f4861daf05aada3c3cdb8df64e7a6bd82c1e974fd684d9/swiglpk-5.0.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ce82748c96dfced697affbed9c22088306f7608601f12f1593e2792ae3ae244", size = 2248153 }, - { url = "https://files.pythonhosted.org/packages/2d/ed/7e44ac6d32c35fc2eb59d2546853ec60a4fde1a4342165789319169c3e87/swiglpk-5.0.10-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e30d85a194991c58acdc3d0374fb524e139d025e76ba46b734f8119316ab9a8d", size = 2115606 }, - { url = "https://files.pythonhosted.org/packages/05/97/2439d56cce729df26602d800b398e29b7e151df5c1f34f0db34db3f05d17/swiglpk-5.0.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b769b09c7af80101095cf1c3f341ac1c7c1f049905ec5da0925c998bbe0cb809", size = 2323950 }, - { url = "https://files.pythonhosted.org/packages/25/4c/262a3e7998edae17f66e64d017247190b8be5e1dd759cb6cd44dd07401e4/swiglpk-5.0.10-cp311-cp311-win32.whl", hash = "sha256:53751ffd429d8adf95aa02ed8a52b5da257958d17dc5a0f344f56379888ac956", size = 463725 }, - { url = "https://files.pythonhosted.org/packages/ef/be/a2b2a21013a8f13bfc947ef541d2927d90dec1ab3298243f2adf6abe5bb5/swiglpk-5.0.10-cp311-cp311-win_amd64.whl", hash = "sha256:eeb066918316034ec9c8dbed0e1e5e14df22761aab7eeb952868eed3716ae344", size = 573108 }, - { url = "https://files.pythonhosted.org/packages/13/ca/9aa218fe08a61c314a53323a692cbdc6dad439b3ef7ded84788684d161f2/swiglpk-5.0.10-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e7862f2a12f09337ef17f1518532f14d4a77a246437eacb4a431f596a7df608e", size = 788285 }, - { url = "https://files.pythonhosted.org/packages/0d/a3/b3b2482a698b8aea2e924eee0d74b967016c07a4d4fc26742da829137ad4/swiglpk-5.0.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e0b1fd9a5d0c20020bb4a624f94ca16b659fdda5e0c59686f88e5d683ab4441b", size = 743813 }, - { url = "https://files.pythonhosted.org/packages/86/59/6a0760bd342f642dd8fb4aea34fbd89fe9162c9fc59ec6a8779376855c23/swiglpk-5.0.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49b1bf4dff2938bc551a4aadaf86b027d1d503d7ef60f8e01d037d88030831c0", size = 2254818 }, - { url = "https://files.pythonhosted.org/packages/11/46/13c7b2f6f8f1fc0378b6177144c4282c32ea413cc13476196939f6643024/swiglpk-5.0.10-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:67156fc1224b82735904d2a0b049664976ff8a0708e15d3e8c823249e3803c6c", size = 2114282 }, - { url = "https://files.pythonhosted.org/packages/ab/a1/84d64bc9a6deb1ebfa0fdeb191777c03919001d1ee04c341a2fcbc91171b/swiglpk-5.0.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:110e8ac831e44a4e09bd7ab1f7b88a4b6ae92b923191e206bccd413ff840ec5c", size = 2330908 }, - { url = "https://files.pythonhosted.org/packages/1e/8b/d0d6a881a8b5c224cec6fc7aad7fc91c3011b5f7c29f1ce0cfc8be6fcf50/swiglpk-5.0.10-cp312-cp312-win32.whl", hash = "sha256:6d9a7e63e9a73a44771413c4d8c59d3442bd63e71b6f01710a1a0c6348030621", size = 464853 }, - { url = "https://files.pythonhosted.org/packages/97/61/de6c95e4750bfbee4af606e14d25ad02a381e0339c5b6e75f122ec7216d0/swiglpk-5.0.10-cp312-cp312-win_amd64.whl", hash = "sha256:d28aac8db80bafc4a91b2d5b6a96791de96eb2d4fea32b8210b11743a0722d42", size = 574484 }, - { url = "https://files.pythonhosted.org/packages/d6/80/9b2f223964ba8a81747b6b5ed55062361a2fb833c717ede900036a9da548/swiglpk-5.0.10-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fb8b722e8dc9e88348ebae54ca19c045dcc6377ce38972d3ae0fbaf9aa4d565f", size = 776944 }, - { url = "https://files.pythonhosted.org/packages/23/6e/251b54dc2ed8896b023f341882cda6f3c81963d96594aec7dd4092778ce3/swiglpk-5.0.10-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:36b99ef9205aa6bea5d8070ef1e07a6a82ebf7449a008c383b9701f50eb0e835", size = 1757363 }, - { url = "https://files.pythonhosted.org/packages/fb/d1/55c113906741e03334d3294f64b0d782202e801c4e35da0638743f713e6b/swiglpk-5.0.10-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f8491ff795b6a146b3ff429c67f04aed5cdc01dc90a7ece8d1b8e1bf22a2e06", size = 1876919 }, +version = "5.0.12" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/6c/9150c5b248eed3a491e5c58642182635956c33b6e03974fcf122f2b0c562/swiglpk-5.0.12.tar.gz", hash = "sha256:86d1be00f24ad59b9e179d3d5132f270535d57be7f209f70f8a6a8b001a65c98", size = 39615, upload-time = "2024-11-25T14:04:41.755Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ae/2b/1e634dbaf15f0d1f438ecbeccd195567df686d5e33618cc8ba44f831b515/swiglpk-5.0.12-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:658ed9afda3920f6ed7db7199b3a890617e948d03851db952885a0ca64fd48e9", size = 787580, upload-time = "2024-11-25T14:03:22.131Z" }, + { url = "https://files.pythonhosted.org/packages/2a/22/1f43e6ac1c050add4ecd73471c269dd3fb746d906d6d81f15849cb968726/swiglpk-5.0.12-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9b7547754ce457baa574a9908adfa22b55eb158451b69bb44c80e3a8032eff56", size = 766036, upload-time = "2024-11-25T14:03:24.597Z" }, + { url = "https://files.pythonhosted.org/packages/27/09/2d9a96b14133d52cbed1d5945759e8eafa8d72da8c4b1a4a624fccc76cb9/swiglpk-5.0.12-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e585632124d3208ba0c5de99449cfa8b9438b342ff20beb7feb5348659b9e5c7", size = 2253219, upload-time = "2024-11-25T14:03:26.351Z" }, + { url = "https://files.pythonhosted.org/packages/98/84/43cbe4c0e1381b2fac5acdc484c2a6e217739ec0af4b2708d3add529df71/swiglpk-5.0.12-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5678317e7257f49adfbfa8d0f7797d309ad9b88d2df97e252931b5660be54b87", size = 2120676, upload-time = "2024-11-25T14:03:28.656Z" }, + { url = "https://files.pythonhosted.org/packages/e2/95/1874263671970c67b34b6b96b79a91935ac0535ff0dc1ba567d6a9926554/swiglpk-5.0.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c8093f72d4314d50f2e3aac54844fffb41c241f33dd5477848aaaefeba1d588", size = 2329424, upload-time = "2024-11-25T14:03:30.412Z" }, + { url = "https://files.pythonhosted.org/packages/24/aa/3e756f09953db14337235d69e514366d147f50ad230efe93a8379ae4d622/swiglpk-5.0.12-cp311-cp311-win32.whl", hash = "sha256:28cdc795b93734f450c07223c24628bc5d796072f3dc8c1546f68865dea88d86", size = 467459, upload-time = "2024-11-25T14:03:32.364Z" }, + { url = "https://files.pythonhosted.org/packages/87/83/dea5bf737f5388292383a10b827eb91a330d8daa510e0c7fead9613a1694/swiglpk-5.0.12-cp311-cp311-win_amd64.whl", hash = "sha256:fc4e7f1ceb7534b380da869f41810507e32b96a0b2b3fd1cfe0b4058eee9e2c3", size = 584614, upload-time = "2024-11-25T14:03:34.101Z" }, + { url = "https://files.pythonhosted.org/packages/be/5f/e8a7e24f7bdad510e43a2fcbb231fd7e96f48d0ab6980bc09416d34ba3fe/swiglpk-5.0.12-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7bd6565a5b75e8648fa232c1ee23f8597da75475691f097d7399ef40de14b482", size = 779114, upload-time = "2024-11-25T14:03:36.949Z" }, + { url = "https://files.pythonhosted.org/packages/86/fb/d4e079319d5c46f0482f77d38281b8f2420083b2058e879b2b69bb2c22d9/swiglpk-5.0.12-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:18773487af5fc92b3063b5c777a3a139518a94201c35572996a6ffef4d710e40", size = 766290, upload-time = "2024-11-25T14:03:38.877Z" }, + { url = "https://files.pythonhosted.org/packages/60/3f/e3c725010a116f193072e1618592174ac965547aaa606620a09cca2852ba/swiglpk-5.0.12-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da0318776acf3892933dfcf6a75b2fe4b26b0334c5513ed6ca7176c0d1b82420", size = 2257547, upload-time = "2024-11-25T14:03:40.665Z" }, + { url = "https://files.pythonhosted.org/packages/03/84/635b666e61dc70a73618665246a9c0f42332a138a9dab041d9f1523b3344/swiglpk-5.0.12-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e60202c809104a07263d0b9c734ca37f644430907a66d7f3155024d83de00b78", size = 2117627, upload-time = "2024-11-25T14:03:42.791Z" }, + { url = "https://files.pythonhosted.org/packages/70/7a/a45aa0a006f4861966dbdbad7cd4c7eef45ee9057929934b7fd5fa30f02a/swiglpk-5.0.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:436f8cc5f3d638a7304ea8397236465017c7b9c4abf668f7c83286609585baaa", size = 2335846, upload-time = "2024-11-25T14:03:45.458Z" }, + { url = "https://files.pythonhosted.org/packages/4a/bb/6955f4a5993427d715e8b021ba4b15c1a9eeb915776addde26703d14da1c/swiglpk-5.0.12-cp312-cp312-win32.whl", hash = "sha256:c541683a0f12e715affde7b1ef766328f2610ac0523f8fee208bb95cb3e774b5", size = 468500, upload-time = "2024-11-25T14:03:47.335Z" }, + { url = "https://files.pythonhosted.org/packages/a7/ef/d864ad0ee5d32bb004018358486f34883d727f0ea5dc4ecfa692188ae81f/swiglpk-5.0.12-cp312-cp312-win_amd64.whl", hash = "sha256:78d0b6e74ad18033c59b3c3e7d6aa058dd28f25e39e71ce54e7a51b04b32e418", size = 584971, upload-time = "2024-11-25T14:03:48.974Z" }, + { url = "https://files.pythonhosted.org/packages/7b/57/7ed7b062139e2553b70a3f8492bf0cdcb877801d365bfd472dd9c40bfbed/swiglpk-5.0.12-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6afea6436ee663d0e86a393bdf3390107294610a1aff346daa5407a272d39f9f", size = 779104, upload-time = "2024-11-25T14:03:50.882Z" }, + { url = "https://files.pythonhosted.org/packages/de/42/447c79d3d813a2ef510af8e70d27b1bf55b04595c321c6857f9135d0249e/swiglpk-5.0.12-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:735a8e8887ae02a1fda34396af6935fd9f4cb76ae5eaeda1cd93a4840bd34402", size = 766296, upload-time = "2024-11-25T14:03:52.524Z" }, + { url = "https://files.pythonhosted.org/packages/13/42/78da14513dec248dd6e82958ba8e4f40a11119f56959744086dfa64a77ed/swiglpk-5.0.12-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bf8f062ebaf14313080db7dd283c0eb313d6ad299cf356242fc7f62658af3f1", size = 2257625, upload-time = "2024-11-25T14:03:54.318Z" }, + { url = "https://files.pythonhosted.org/packages/58/76/992329f37828e7e714040c0e138de904fdaaa623ebd6004f191d293f2b3b/swiglpk-5.0.12-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9f30911986d5a2e8e556ae75c518578d9bf2b8d0f5c6656398682df682e284ad", size = 2117573, upload-time = "2024-11-25T14:03:56.056Z" }, + { url = "https://files.pythonhosted.org/packages/84/a9/f0b7165137d7cb877f8d4c5670ccd8bd73d03c9e1080d382f470308e31e3/swiglpk-5.0.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:190346671880aad44bcd96d13d2d8b0373b5bbffa20577b85f494935381190c9", size = 2335716, upload-time = "2024-11-25T14:03:57.783Z" }, + { url = "https://files.pythonhosted.org/packages/3c/6a/17a213168743418176220372b0472dbdc8561f5b79332b4ba0c29359c573/swiglpk-5.0.12-cp313-cp313-win32.whl", hash = "sha256:e73bd3747f4e06d03817630f70e915fa263d1eaddb100e87da68fe0f00352072", size = 468493, upload-time = "2024-11-25T14:03:59.461Z" }, + { url = "https://files.pythonhosted.org/packages/13/20/74e42a09b9aa1653171f0d65af63d17c61beec2be64279c5056db569847c/swiglpk-5.0.12-cp313-cp313-win_amd64.whl", hash = "sha256:6c64594860dcf9ee64020e924cf64032ef3d5ac474220e26bc900486ff2f6b58", size = 584967, upload-time = "2024-11-25T14:04:01.175Z" }, ] [[package]] name = "sympy" -version = "1.13.3" +version = "1.14.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mpmath" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/11/8a/5a7fd6284fa8caac23a26c9ddf9c30485a48169344b4bd3b0f02fef1890f/sympy-1.13.3.tar.gz", hash = "sha256:b27fd2c6530e0ab39e275fc9b683895367e51d5da91baa8d3d64db2565fec4d9", size = 7533196 } +sdist = { url = "https://files.pythonhosted.org/packages/83/d3/803453b36afefb7c2bb238361cd4ae6125a569b4db67cd9e79846ba2d68c/sympy-1.14.0.tar.gz", hash = "sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517", size = 7793921, upload-time = "2025-04-27T18:05:01.611Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/99/ff/c87e0622b1dadea79d2fb0b25ade9ed98954c9033722eb707053d310d4f3/sympy-1.13.3-py3-none-any.whl", hash = "sha256:54612cf55a62755ee71824ce692986f23c88ffa77207b30c1368eda4a7060f73", size = 6189483 }, + { url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353, upload-time = "2025-04-27T18:04:59.103Z" }, ] [[package]] name = "termcolor" -version = "2.5.0" +version = "3.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/37/72/88311445fd44c455c7d553e61f95412cf89054308a1aa2434ab835075fc5/termcolor-2.5.0.tar.gz", hash = "sha256:998d8d27da6d48442e8e1f016119076b690d962507531df4890fcd2db2ef8a6f", size = 13057 } +sdist = { url = "https://files.pythonhosted.org/packages/ca/6c/3d75c196ac07ac8749600b60b03f4f6094d54e132c4d94ebac6ee0e0add0/termcolor-3.1.0.tar.gz", hash = "sha256:6a6dd7fbee581909eeec6a756cff1d7f7c376063b14e4a298dc4980309e55970", size = 14324, upload-time = "2025-04-30T11:37:53.791Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7f/be/df630c387a0a054815d60be6a97eb4e8f17385d5d6fe660e1c02750062b4/termcolor-2.5.0-py3-none-any.whl", hash = "sha256:37b17b5fc1e604945c2642c872a3764b5d547a48009871aea3edd3afa180afb8", size = 7755 }, + { url = "https://files.pythonhosted.org/packages/4f/bd/de8d508070629b6d84a30d01d57e4a65c69aa7f5abe7560b8fad3b50ea59/termcolor-3.1.0-py3-none-any.whl", hash = "sha256:591dd26b5c2ce03b9e43f391264626557873ce1d379019786f99b0c2bee140aa", size = 7684, upload-time = "2025-04-30T11:37:52.382Z" }, ] [[package]] @@ -2751,18 +3303,18 @@ dependencies = [ { name = "pywinpty", marker = "os_name == 'nt'" }, { name = "tornado" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8a/11/965c6fd8e5cc254f1fe142d547387da17a8ebfd75a3455f637c663fb38a0/terminado-0.18.1.tar.gz", hash = "sha256:de09f2c4b85de4765f7714688fff57d3e75bad1f909b589fde880460c753fd2e", size = 32701 } +sdist = { url = "https://files.pythonhosted.org/packages/8a/11/965c6fd8e5cc254f1fe142d547387da17a8ebfd75a3455f637c663fb38a0/terminado-0.18.1.tar.gz", hash = "sha256:de09f2c4b85de4765f7714688fff57d3e75bad1f909b589fde880460c753fd2e", size = 32701, upload-time = "2024-03-12T14:34:39.026Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl", hash = "sha256:a4468e1b37bb318f8a86514f65814e1afc977cf29b3992a4500d9dd305dcceb0", size = 14154 }, + { url = "https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl", hash = "sha256:a4468e1b37bb318f8a86514f65814e1afc977cf29b3992a4500d9dd305dcceb0", size = 14154, upload-time = "2024-03-12T14:34:36.569Z" }, ] [[package]] name = "threadpoolctl" -version = "3.5.0" +version = "3.6.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bd/55/b5148dcbf72f5cde221f8bfe3b6a540da7aa1842f6b491ad979a6c8b84af/threadpoolctl-3.5.0.tar.gz", hash = "sha256:082433502dd922bf738de0d8bcc4fdcbf0979ff44c42bd40f5af8a282f6fa107", size = 41936 } +sdist = { url = "https://files.pythonhosted.org/packages/b7/4d/08c89e34946fce2aec4fbb45c9016efd5f4d7f24af8e5d93296e935631d8/threadpoolctl-3.6.0.tar.gz", hash = "sha256:8ab8b4aa3491d812b623328249fab5302a68d2d71745c8a4c719a2fcaba9f44e", size = 21274, upload-time = "2025-03-13T13:49:23.031Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4b/2c/ffbf7a134b9ab11a67b0cf0726453cedd9c5043a4fe7a35d1cefa9a1bcfb/threadpoolctl-3.5.0-py3-none-any.whl", hash = "sha256:56c1e26c150397e58c4926da8eeee87533b1e32bef131bd4bf6a2f45f3185467", size = 18414 }, + { url = "https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl", hash = "sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb", size = 18638, upload-time = "2025-03-13T13:49:21.846Z" }, ] [[package]] @@ -2772,66 +3324,97 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "webencodings" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7a/fd/7a5ee21fd08ff70d3d33a5781c255cbe779659bd03278feb98b19ee550f4/tinycss2-1.4.0.tar.gz", hash = "sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7", size = 87085 } +sdist = { url = "https://files.pythonhosted.org/packages/7a/fd/7a5ee21fd08ff70d3d33a5781c255cbe779659bd03278feb98b19ee550f4/tinycss2-1.4.0.tar.gz", hash = "sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7", size = 87085, upload-time = "2024-10-24T14:58:29.895Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl", hash = "sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289", size = 26610 }, + { url = "https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl", hash = "sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289", size = 26610, upload-time = "2024-10-24T14:58:28.029Z" }, ] [[package]] name = "tomli" -version = "2.0.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/35/b9/de2a5c0144d7d75a57ff355c0c24054f965b2dc3036456ae03a51ea6264b/tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed", size = 16096 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cf/db/ce8eda256fa131af12e0a76d481711abe4681b6923c27efb9a255c9e4594/tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38", size = 13237 }, +version = "2.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175, upload-time = "2024-11-27T22:38:36.873Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077, upload-time = "2024-11-27T22:37:54.956Z" }, + { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429, upload-time = "2024-11-27T22:37:56.698Z" }, + { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067, upload-time = "2024-11-27T22:37:57.63Z" }, + { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030, upload-time = "2024-11-27T22:37:59.344Z" }, + { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898, upload-time = "2024-11-27T22:38:00.429Z" }, + { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894, upload-time = "2024-11-27T22:38:02.094Z" }, + { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319, upload-time = "2024-11-27T22:38:03.206Z" }, + { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273, upload-time = "2024-11-27T22:38:04.217Z" }, + { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310, upload-time = "2024-11-27T22:38:05.908Z" }, + { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309, upload-time = "2024-11-27T22:38:06.812Z" }, + { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762, upload-time = "2024-11-27T22:38:07.731Z" }, + { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453, upload-time = "2024-11-27T22:38:09.384Z" }, + { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486, upload-time = "2024-11-27T22:38:10.329Z" }, + { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349, upload-time = "2024-11-27T22:38:11.443Z" }, + { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159, upload-time = "2024-11-27T22:38:13.099Z" }, + { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243, upload-time = "2024-11-27T22:38:14.766Z" }, + { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645, upload-time = "2024-11-27T22:38:15.843Z" }, + { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584, upload-time = "2024-11-27T22:38:17.645Z" }, + { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875, upload-time = "2024-11-27T22:38:19.159Z" }, + { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418, upload-time = "2024-11-27T22:38:20.064Z" }, + { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708, upload-time = "2024-11-27T22:38:21.659Z" }, + { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582, upload-time = "2024-11-27T22:38:22.693Z" }, + { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543, upload-time = "2024-11-27T22:38:24.367Z" }, + { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691, upload-time = "2024-11-27T22:38:26.081Z" }, + { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170, upload-time = "2024-11-27T22:38:27.921Z" }, + { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530, upload-time = "2024-11-27T22:38:29.591Z" }, + { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666, upload-time = "2024-11-27T22:38:30.639Z" }, + { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954, upload-time = "2024-11-27T22:38:31.702Z" }, + { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724, upload-time = "2024-11-27T22:38:32.837Z" }, + { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383, upload-time = "2024-11-27T22:38:34.455Z" }, + { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257, upload-time = "2024-11-27T22:38:35.385Z" }, ] [[package]] name = "tomlkit" -version = "0.13.2" +version = "0.13.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b1/09/a439bec5888f00a54b8b9f05fa94d7f901d6735ef4e55dcec9bc37b5d8fa/tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79", size = 192885 } +sdist = { url = "https://files.pythonhosted.org/packages/cc/18/0bbf3884e9eaa38819ebe46a7bd25dcd56b67434402b66a58c4b8e552575/tomlkit-0.13.3.tar.gz", hash = "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1", size = 185207, upload-time = "2025-06-05T07:13:44.947Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f9/b6/a447b5e4ec71e13871be01ba81f5dfc9d0af7e473da256ff46bc0e24026f/tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde", size = 37955 }, + { url = "https://files.pythonhosted.org/packages/bd/75/8539d011f6be8e29f339c42e633aae3cb73bffa95dd0f9adec09b9c58e85/tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0", size = 38901, upload-time = "2025-06-05T07:13:43.546Z" }, ] [[package]] name = "tornado" -version = "6.4.2" +version = "6.5.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/59/45/a0daf161f7d6f36c3ea5fc0c2de619746cc3dd4c76402e9db545bd920f63/tornado-6.4.2.tar.gz", hash = "sha256:92bad5b4746e9879fd7bf1eb21dce4e3fc5128d71601f80005afa39237ad620b", size = 501135 } +sdist = { url = "https://files.pythonhosted.org/packages/09/ce/1eb500eae19f4648281bb2186927bb062d2438c2e5093d1360391afd2f90/tornado-6.5.2.tar.gz", hash = "sha256:ab53c8f9a0fa351e2c0741284e06c7a45da86afb544133201c5cc8578eb076a0", size = 510821, upload-time = "2025-08-08T18:27:00.78Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/26/7e/71f604d8cea1b58f82ba3590290b66da1e72d840aeb37e0d5f7291bd30db/tornado-6.4.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e828cce1123e9e44ae2a50a9de3055497ab1d0aeb440c5ac23064d9e44880da1", size = 436299 }, - { url = "https://files.pythonhosted.org/packages/96/44/87543a3b99016d0bf54fdaab30d24bf0af2e848f1d13d34a3a5380aabe16/tornado-6.4.2-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:072ce12ada169c5b00b7d92a99ba089447ccc993ea2143c9ede887e0937aa803", size = 434253 }, - { url = "https://files.pythonhosted.org/packages/cb/fb/fdf679b4ce51bcb7210801ef4f11fdac96e9885daa402861751353beea6e/tornado-6.4.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a017d239bd1bb0919f72af256a970624241f070496635784d9bf0db640d3fec", size = 437602 }, - { url = "https://files.pythonhosted.org/packages/4f/3b/e31aeffffc22b475a64dbeb273026a21b5b566f74dee48742817626c47dc/tornado-6.4.2-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c36e62ce8f63409301537222faffcef7dfc5284f27eec227389f2ad11b09d946", size = 436972 }, - { url = "https://files.pythonhosted.org/packages/22/55/b78a464de78051a30599ceb6983b01d8f732e6f69bf37b4ed07f642ac0fc/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", size = 437173 }, - { url = "https://files.pythonhosted.org/packages/79/5e/be4fb0d1684eb822c9a62fb18a3e44a06188f78aa466b2ad991d2ee31104/tornado-6.4.2-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:304463bd0772442ff4d0f5149c6f1c2135a1fae045adf070821c6cdc76980634", size = 437892 }, - { url = "https://files.pythonhosted.org/packages/f5/33/4f91fdd94ea36e1d796147003b490fe60a0215ac5737b6f9c65e160d4fe0/tornado-6.4.2-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:c82c46813ba483a385ab2a99caeaedf92585a1f90defb5693351fa7e4ea0bf73", size = 437334 }, - { url = "https://files.pythonhosted.org/packages/2b/ae/c1b22d4524b0e10da2f29a176fb2890386f7bd1f63aacf186444873a88a0/tornado-6.4.2-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:932d195ca9015956fa502c6b56af9eb06106140d844a335590c1ec7f5277d10c", size = 437261 }, - { url = "https://files.pythonhosted.org/packages/b5/25/36dbd49ab6d179bcfc4c6c093a51795a4f3bed380543a8242ac3517a1751/tornado-6.4.2-cp38-abi3-win32.whl", hash = "sha256:2876cef82e6c5978fde1e0d5b1f919d756968d5b4282418f3146b79b58556482", size = 438463 }, - { url = "https://files.pythonhosted.org/packages/61/cc/58b1adeb1bb46228442081e746fcdbc4540905c87e8add7c277540934edb/tornado-6.4.2-cp38-abi3-win_amd64.whl", hash = "sha256:908b71bf3ff37d81073356a5fadcc660eb10c1476ee6e2725588626ce7e5ca38", size = 438907 }, + { url = "https://files.pythonhosted.org/packages/f6/48/6a7529df2c9cc12efd2e8f5dd219516184d703b34c06786809670df5b3bd/tornado-6.5.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:2436822940d37cde62771cff8774f4f00b3c8024fe482e16ca8387b8a2724db6", size = 442563, upload-time = "2025-08-08T18:26:42.945Z" }, + { url = "https://files.pythonhosted.org/packages/f2/b5/9b575a0ed3e50b00c40b08cbce82eb618229091d09f6d14bce80fc01cb0b/tornado-6.5.2-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:583a52c7aa94ee046854ba81d9ebb6c81ec0fd30386d96f7640c96dad45a03ef", size = 440729, upload-time = "2025-08-08T18:26:44.473Z" }, + { url = "https://files.pythonhosted.org/packages/1b/4e/619174f52b120efcf23633c817fd3fed867c30bff785e2cd5a53a70e483c/tornado-6.5.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0fe179f28d597deab2842b86ed4060deec7388f1fd9c1b4a41adf8af058907e", size = 444295, upload-time = "2025-08-08T18:26:46.021Z" }, + { url = "https://files.pythonhosted.org/packages/95/fa/87b41709552bbd393c85dd18e4e3499dcd8983f66e7972926db8d96aa065/tornado-6.5.2-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b186e85d1e3536d69583d2298423744740986018e393d0321df7340e71898882", size = 443644, upload-time = "2025-08-08T18:26:47.625Z" }, + { url = "https://files.pythonhosted.org/packages/f9/41/fb15f06e33d7430ca89420283a8762a4e6b8025b800ea51796ab5e6d9559/tornado-6.5.2-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e792706668c87709709c18b353da1f7662317b563ff69f00bab83595940c7108", size = 443878, upload-time = "2025-08-08T18:26:50.599Z" }, + { url = "https://files.pythonhosted.org/packages/11/92/fe6d57da897776ad2e01e279170ea8ae726755b045fe5ac73b75357a5a3f/tornado-6.5.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:06ceb1300fd70cb20e43b1ad8aaee0266e69e7ced38fa910ad2e03285009ce7c", size = 444549, upload-time = "2025-08-08T18:26:51.864Z" }, + { url = "https://files.pythonhosted.org/packages/9b/02/c8f4f6c9204526daf3d760f4aa555a7a33ad0e60843eac025ccfd6ff4a93/tornado-6.5.2-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:74db443e0f5251be86cbf37929f84d8c20c27a355dd452a5cfa2aada0d001ec4", size = 443973, upload-time = "2025-08-08T18:26:53.625Z" }, + { url = "https://files.pythonhosted.org/packages/ae/2d/f5f5707b655ce2317190183868cd0f6822a1121b4baeae509ceb9590d0bd/tornado-6.5.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b5e735ab2889d7ed33b32a459cac490eda71a1ba6857b0118de476ab6c366c04", size = 443954, upload-time = "2025-08-08T18:26:55.072Z" }, + { url = "https://files.pythonhosted.org/packages/e8/59/593bd0f40f7355806bf6573b47b8c22f8e1374c9b6fd03114bd6b7a3dcfd/tornado-6.5.2-cp39-abi3-win32.whl", hash = "sha256:c6f29e94d9b37a95013bb669616352ddb82e3bfe8326fccee50583caebc8a5f0", size = 445023, upload-time = "2025-08-08T18:26:56.677Z" }, + { url = "https://files.pythonhosted.org/packages/c7/2a/f609b420c2f564a748a2d80ebfb2ee02a73ca80223af712fca591386cafb/tornado-6.5.2-cp39-abi3-win_amd64.whl", hash = "sha256:e56a5af51cc30dd2cae649429af65ca2f6571da29504a07995175df14c18f35f", size = 445427, upload-time = "2025-08-08T18:26:57.91Z" }, + { url = "https://files.pythonhosted.org/packages/5e/4f/e1f65e8f8c76d73658b33d33b81eed4322fb5085350e4328d5c956f0c8f9/tornado-6.5.2-cp39-abi3-win_arm64.whl", hash = "sha256:d6c33dc3672e3a1f3618eb63b7ef4683a7688e7b9e6e8f0d9aa5726360a004af", size = 444456, upload-time = "2025-08-08T18:26:59.207Z" }, ] [[package]] name = "tqdm" -version = "4.66.6" +version = "4.67.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e9/34/bef135b27fe1864993a5284ad001157ee9b5538e859ac90f5b0e8cc8c9ec/tqdm-4.66.6.tar.gz", hash = "sha256:4bdd694238bef1485ce839d67967ab50af8f9272aab687c0d7702a01da0be090", size = 169533 } +sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737, upload-time = "2024-11-24T20:12:22.481Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/41/73/02342de9c2d20922115f787e101527b831c0cffd2105c946c4a4826bcfd4/tqdm-4.66.6-py3-none-any.whl", hash = "sha256:223e8b5359c2efc4b30555531f09e9f2f3589bcd7fdd389271191031b49b7a63", size = 78326 }, + { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload-time = "2024-11-24T20:12:19.698Z" }, ] [[package]] name = "traitlets" version = "5.14.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/eb/79/72064e6a701c2183016abbbfedaba506d81e30e232a68c9f0d6f6fcd1574/traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7", size = 161621 } +sdist = { url = "https://files.pythonhosted.org/packages/eb/79/72064e6a701c2183016abbbfedaba506d81e30e232a68c9f0d6f6fcd1574/traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7", size = 161621, upload-time = "2024-04-19T11:11:49.746Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359 }, + { url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359, upload-time = "2024-04-19T11:11:46.763Z" }, ] [[package]] @@ -2846,34 +3429,55 @@ dependencies = [ [[package]] name = "types-python-dateutil" -version = "2.9.0.20241206" +version = "2.9.0.20250822" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0c/0a/775f8551665992204c756be326f3575abba58c4a3a52eef9909ef4536428/types_python_dateutil-2.9.0.20250822.tar.gz", hash = "sha256:84c92c34bd8e68b117bff742bc00b692a1e8531262d4507b33afcc9f7716cd53", size = 16084, upload-time = "2025-08-22T03:02:00.613Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/d9/a29dfa84363e88b053bf85a8b7f212a04f0d7343a4d24933baa45c06e08b/types_python_dateutil-2.9.0.20250822-py3-none-any.whl", hash = "sha256:849d52b737e10a6dc6621d2bd7940ec7c65fcb69e6aa2882acf4e56b2b508ddc", size = 17892, upload-time = "2025-08-22T03:01:59.436Z" }, +] + +[[package]] +name = "types-pytz" +version = "2025.2.0.20250809" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a9/60/47d92293d9bc521cd2301e423a358abfac0ad409b3a1606d8fbae1321961/types_python_dateutil-2.9.0.20241206.tar.gz", hash = "sha256:18f493414c26ffba692a72369fea7a154c502646301ebfe3d56a04b3767284cb", size = 13802 } +sdist = { url = "https://files.pythonhosted.org/packages/07/e2/c774f754de26848f53f05defff5bb21dd9375a059d1ba5b5ea943cf8206e/types_pytz-2025.2.0.20250809.tar.gz", hash = "sha256:222e32e6a29bb28871f8834e8785e3801f2dc4441c715cd2082b271eecbe21e5", size = 10876, upload-time = "2025-08-09T03:14:17.453Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0f/b3/ca41df24db5eb99b00d97f89d7674a90cb6b3134c52fb8121b6d8d30f15c/types_python_dateutil-2.9.0.20241206-py3-none-any.whl", hash = "sha256:e248a4bc70a486d3e3ec84d0dc30eec3a5f979d6e7ee4123ae043eedbb987f53", size = 14384 }, + { url = "https://files.pythonhosted.org/packages/db/d0/91c24fe54e565f2344d7a6821e6c6bb099841ef09007ea6321a0bac0f808/types_pytz-2025.2.0.20250809-py3-none-any.whl", hash = "sha256:4f55ed1b43e925cf851a756fe1707e0f5deeb1976e15bf844bcaa025e8fbd0db", size = 10095, upload-time = "2025-08-09T03:14:16.674Z" }, ] [[package]] name = "typing-extensions" -version = "4.12.2" +version = "4.15.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f8/b1/0c11f5058406b3af7609f121aaa6b609744687f1d158b3c3a5bf4cc94238/typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28", size = 75726, upload-time = "2025-05-21T18:55:23.885Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51", size = 14552, upload-time = "2025-05-21T18:55:22.152Z" }, ] [[package]] name = "tzdata" -version = "2024.2" +version = "2025.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e1/34/943888654477a574a86a98e9896bae89c7aa15078ec29f490fef2f1e5384/tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc", size = 193282 } +sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380, upload-time = "2025-03-23T13:54:43.652Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a6/ab/7e5f53c3b9d14972843a647d8d7a853969a58aecc7559cb3267302c94774/tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd", size = 346586 }, + { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" }, ] [[package]] name = "umap-learn" -version = "0.5.7" +version = "0.5.9.post2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numba" }, @@ -2883,79 +3487,146 @@ dependencies = [ { name = "scipy" }, { name = "tqdm" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6f/d4/9ed627905f7993349671283b3c5bf2d9f543ef79229fa1c7e01324eb900c/umap-learn-0.5.7.tar.gz", hash = "sha256:b2a97973e4c6ffcebf241100a8de589a4c84126a832ab40f296c6d9fcc5eb19e", size = 92680 } +sdist = { url = "https://files.pythonhosted.org/packages/5f/ee/6bc65bd375c812026a7af63fe9d09d409382120aff25f2152f1ba12af5ec/umap_learn-0.5.9.post2.tar.gz", hash = "sha256:bdf60462d779bd074ce177a0714ced17e6d161285590fa487f3f9548dd3c31c9", size = 95441, upload-time = "2025-07-03T00:18:02.479Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3c/8f/671c0e1f2572ba625cbcc1faeba9435e00330c3d6962858711445cf1e817/umap_learn-0.5.7-py3-none-any.whl", hash = "sha256:6a7e0be2facfa365a5ed6588447102bdbef32a0ef449535c25c97ea7e680073c", size = 88815 }, + { url = "https://files.pythonhosted.org/packages/6b/b1/c24deeda9baf1fd491aaad941ed89e0fed6c583a117fd7b79e0a33a1e6c0/umap_learn-0.5.9.post2-py3-none-any.whl", hash = "sha256:fbe51166561e0e7fab00ef3d516ac2621243b8d15cf4bef9f656d701736b16a0", size = 90146, upload-time = "2025-07-03T00:18:01.042Z" }, ] [[package]] name = "uri-template" version = "1.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/31/c7/0336f2bd0bcbada6ccef7aaa25e443c118a704f828a0620c6fa0207c1b64/uri-template-1.3.0.tar.gz", hash = "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7", size = 21678 } +sdist = { url = "https://files.pythonhosted.org/packages/31/c7/0336f2bd0bcbada6ccef7aaa25e443c118a704f828a0620c6fa0207c1b64/uri-template-1.3.0.tar.gz", hash = "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7", size = 21678, upload-time = "2023-06-21T01:49:05.374Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363", size = 11140 }, + { url = "https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363", size = 11140, upload-time = "2023-06-21T01:49:03.467Z" }, ] [[package]] name = "urllib3" -version = "2.2.3" +version = "2.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ed/63/22ba4ebfe7430b76388e7cd448d5478814d3032121827c12a2cc287e2260/urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9", size = 300677 } +sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ce/d9/5f4c13cecde62396b0d3fe530a50ccea91e7dfc1ccf0e09c228841bb5ba8/urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", size = 126338 }, + { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, +] + +[[package]] +name = "virtualenv" +version = "20.34.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "distlib" }, + { name = "filelock" }, + { name = "platformdirs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1c/14/37fcdba2808a6c615681cd216fecae00413c9dab44fb2e57805ecf3eaee3/virtualenv-20.34.0.tar.gz", hash = "sha256:44815b2c9dee7ed86e387b842a84f20b93f7f417f95886ca1996a72a4138eb1a", size = 6003808, upload-time = "2025-08-13T14:24:07.464Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/06/04c8e804f813cf972e3262f3f8584c232de64f0cde9f703b46cf53a45090/virtualenv-20.34.0-py3-none-any.whl", hash = "sha256:341f5afa7eee943e4984a9207c025feedd768baff6753cd660c857ceb3e36026", size = 5983279, upload-time = "2025-08-13T14:24:05.111Z" }, ] [[package]] name = "wcwidth" version = "0.2.13" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6c/63/53559446a878410fc5a5974feb13d31d78d752eb18aeba59c7fef1af7598/wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5", size = 101301 } +sdist = { url = "https://files.pythonhosted.org/packages/6c/63/53559446a878410fc5a5974feb13d31d78d752eb18aeba59c7fef1af7598/wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5", size = 101301, upload-time = "2024-01-06T02:10:57.829Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", size = 34166 }, + { url = "https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", size = 34166, upload-time = "2024-01-06T02:10:55.763Z" }, ] [[package]] name = "webcolors" version = "24.11.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7b/29/061ec845fb58521848f3739e466efd8250b4b7b98c1b6c5bf4d40b419b7e/webcolors-24.11.1.tar.gz", hash = "sha256:ecb3d768f32202af770477b8b65f318fa4f566c22948673a977b00d589dd80f6", size = 45064 } +sdist = { url = "https://files.pythonhosted.org/packages/7b/29/061ec845fb58521848f3739e466efd8250b4b7b98c1b6c5bf4d40b419b7e/webcolors-24.11.1.tar.gz", hash = "sha256:ecb3d768f32202af770477b8b65f318fa4f566c22948673a977b00d589dd80f6", size = 45064, upload-time = "2024-11-11T07:43:24.224Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/60/e8/c0e05e4684d13459f93d312077a9a2efbe04d59c393bc2b8802248c908d4/webcolors-24.11.1-py3-none-any.whl", hash = "sha256:515291393b4cdf0eb19c155749a096f779f7d909f7cceea072791cb9095b92e9", size = 14934 }, + { url = "https://files.pythonhosted.org/packages/60/e8/c0e05e4684d13459f93d312077a9a2efbe04d59c393bc2b8802248c908d4/webcolors-24.11.1-py3-none-any.whl", hash = "sha256:515291393b4cdf0eb19c155749a096f779f7d909f7cceea072791cb9095b92e9", size = 14934, upload-time = "2024-11-11T07:43:22.529Z" }, ] [[package]] name = "webencodings" version = "0.5.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0b/02/ae6ceac1baeda530866a85075641cec12989bd8d31af6d5ab4a3e8c92f47/webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923", size = 9721 } +sdist = { url = "https://files.pythonhosted.org/packages/0b/02/ae6ceac1baeda530866a85075641cec12989bd8d31af6d5ab4a3e8c92f47/webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923", size = 9721, upload-time = "2017-04-05T20:21:34.189Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", size = 11774 }, + { url = "https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", size = 11774, upload-time = "2017-04-05T20:21:32.581Z" }, ] [[package]] name = "websocket-client" version = "1.8.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e6/30/fba0d96b4b5fbf5948ed3f4681f7da2f9f64512e1d303f94b4cc174c24a5/websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da", size = 54648 } +sdist = { url = "https://files.pythonhosted.org/packages/e6/30/fba0d96b4b5fbf5948ed3f4681f7da2f9f64512e1d303f94b4cc174c24a5/websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da", size = 54648, upload-time = "2024-04-23T22:16:16.976Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/84/44687a29792a70e111c5c477230a72c4b957d88d16141199bf9acb7537a3/websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526", size = 58826 }, + { url = "https://files.pythonhosted.org/packages/5a/84/44687a29792a70e111c5c477230a72c4b957d88d16141199bf9acb7537a3/websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526", size = 58826, upload-time = "2024-04-23T22:16:14.422Z" }, ] [[package]] name = "win32-setctime" -version = "1.1.0" +version = "1.2.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6b/dd/f95a13d2b235a28d613ba23ebad55191514550debb968b46aab99f2e3a30/win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2", size = 3676 } +sdist = { url = "https://files.pythonhosted.org/packages/b3/8f/705086c9d734d3b663af0e9bb3d4de6578d08f46b1b101c2442fd9aecaa2/win32_setctime-1.2.0.tar.gz", hash = "sha256:ae1fdf948f5640aae05c511ade119313fb6a30d7eabe25fef9764dca5873c4c0", size = 4867, upload-time = "2024-12-07T15:28:28.314Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0a/e6/a7d828fef907843b2a5773ebff47fb79ac0c1c88d60c0ca9530ee941e248/win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad", size = 3604 }, + { url = "https://files.pythonhosted.org/packages/e1/07/c6fe3ad3e685340704d314d765b7912993bcb8dc198f0e7a89382d37974b/win32_setctime-1.2.0-py3-none-any.whl", hash = "sha256:95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390", size = 4083, upload-time = "2024-12-07T15:28:26.465Z" }, +] + +[[package]] +name = "xarray" +version = "2025.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "packaging" }, + { name = "pandas" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d2/55/18055bc943029d25fb8f260b7e3b1485c30646ccf503a5e4a744d31a3b78/xarray-2025.8.0.tar.gz", hash = "sha256:323d4169ce72d4ef849de2b0bd122f9cd2905b82c7558169930dc16070982bab", size = 3034425, upload-time = "2025-08-14T16:52:13.872Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e6/c8/0f8db9d9478de8d70cbcae2056588401e26168e269d6d9919bf2ecb01f78/xarray-2025.8.0-py3-none-any.whl", hash = "sha256:1c454f32b38c93df68e450238c9473fe21248b8572d42ddd58c5170bb30934ee", size = 1342279, upload-time = "2025-08-14T16:52:10.956Z" }, +] + +[[package]] +name = "xarray-einstats" +version = "0.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, + { name = "scipy" }, + { name = "xarray" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f1/10/ef474494a7f2102ec4c02352c723fa282c6237b600565eb82ee354291211/xarray_einstats-0.9.1.tar.gz", hash = "sha256:39b373deed43592c41d3fbf8863af62e19e01c1ae553ae5ff059a8df78d995c6", size = 33327, upload-time = "2025-06-18T15:53:28.499Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/17/8b/ed2f0f49385c3d7739cd4699954add26e8f09a372a0c3f04f2bde32fcea2/xarray_einstats-0.9.1-py3-none-any.whl", hash = "sha256:777339524e85d066f2ef9ed1e3a3fb63aead4c1065fd1406f30dfa4de58ce063", size = 39043, upload-time = "2025-06-18T15:53:24.088Z" }, ] [[package]] name = "xlrd" -version = "2.0.1" +version = "2.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/07/5a/377161c2d3538d1990d7af382c79f3b2372e880b65de21b01b1a2b78691e/xlrd-2.0.2.tar.gz", hash = "sha256:08b5e25de58f21ce71dc7db3b3b8106c1fa776f3024c54e45b45b374e89234c9", size = 100167, upload-time = "2025-06-14T08:46:39.039Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1a/62/c8d562e7766786ba6587d09c5a8ba9f718ed3fa8af7f4553e8f91c36f302/xlrd-2.0.2-py2.py3-none-any.whl", hash = "sha256:ea762c3d29f4cca48d82df517b6d89fbce4db3107f9d78713e48cd321d5c9aa9", size = 96555, upload-time = "2025-06-14T08:46:37.766Z" }, +] + +[[package]] +name = "zarr" +version = "3.1.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "donfig" }, + { name = "numcodecs", extra = ["crc32c"] }, + { name = "numpy" }, + { name = "packaging" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/09/04/76261cf5bd065648b7981b41ba1936b8bd9565f80f69534e3cdf2d772ad9/zarr-3.1.2.tar.gz", hash = "sha256:688e4eb79045c110128cd16f301f2f58fa19507b1803dcbea0ea894e66e06274", size = 324221, upload-time = "2025-08-25T15:32:31.153Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/a3/d3d4fd394a10b1256f9dccb2fe0ddd125fc575d7c437b1c70df050f14176/zarr-3.1.2-py3-none-any.whl", hash = "sha256:c3e180f53ee0ef91b86f7feff6f9dd381ddd1b512d1a46580530966a493387b6", size = 261041, upload-time = "2025-08-25T15:32:29.522Z" }, +] + +[[package]] +name = "zipp" +version = "3.23.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a6/b3/19a2540d21dea5f908304375bd43f5ed7a4c28a370dc9122c565423e6b44/xlrd-2.0.1.tar.gz", hash = "sha256:f72f148f54442c6b056bf931dbc34f986fd0c3b0b6b5a58d013c9aef274d0c88", size = 100259 } +sdist = { url = "https://files.pythonhosted.org/packages/e3/02/0f2892c661036d50ede074e376733dca2ae7c6eb617489437771209d4180/zipp-3.23.0.tar.gz", hash = "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166", size = 25547, upload-time = "2025-06-08T17:06:39.4Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a6/0c/c2a72d51fe56e08a08acc85d13013558a2d793028ae7385448a6ccdfae64/xlrd-2.0.1-py2.py3-none-any.whl", hash = "sha256:6a33ee89877bd9abc1158129f6e94be74e2679636b8a205b43b85206c3f0bbdd", size = 96531 }, + { url = "https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e", size = 10276, upload-time = "2025-06-08T17:06:38.034Z" }, ] From ca99e0a323c0143db7606b2518b952d7379f8fb5 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 5 Sep 2025 11:14:28 -0500 Subject: [PATCH 218/265] fix: swap minimum and maximum bounds for exchange reactions Signed-off-by: Josh Loecker --- .../boundary_rxns/naiveB_boundary_rxns.csv | 102 +++++++++--------- main/data/boundary_rxns/smB_boundary_rxns.csv | 4 +- 2 files changed, 53 insertions(+), 53 deletions(-) diff --git a/main/data/boundary_rxns/naiveB_boundary_rxns.csv b/main/data/boundary_rxns/naiveB_boundary_rxns.csv index 0b08556e..be3eec35 100644 --- a/main/data/boundary_rxns/naiveB_boundary_rxns.csv +++ b/main/data/boundary_rxns/naiveB_boundary_rxns.csv @@ -1,7 +1,7 @@ -Boundary,Abbreviation,Compartment,Minimum Reaction Rate,Maximum Reaction Rate -Exchange,glc_D,Extracellular,-100,1000 +Reaction,Abbreviation,Compartment,Minimum Reaction Rate,Maximum Reaction Rate +Exchange,glc_D,Extracellular,-1000,100 Exchange,fe2,Extracellular,-1000,1000 -Exchange,gal,Extracellular,0,1000 +Exchange,gal,Extracellular,-1000,0 Exchange,zn2,Extracellular,-1000,1000 Exchange,ca2,Extracellular,-1000,1000 Exchange,na1,Extracellular,-1000,1000 @@ -16,55 +16,55 @@ Exchange,co2,Extracellular,-1000,1000 Exchange,nh4,Extracellular,-1000,1000 Exchange,no2,Extracellular,-1000,1000 Exchange,co,Extracellular,-1000,1000 -Exchange,asn_L,Extracellular,-1,1000 -Exchange,asp_L,Extracellular,-1,1000 -Exchange,glu_L,Extracellular,-1,1000 -Exchange,ile_L,Extracellular,-1,1000 -Exchange,leu_L,Extracellular,-1,1000 -Exchange,lys_L,Extracellular,-1,1000 -Exchange,met_L,Extracellular,-1,1000 -Exchange,pro_L,Extracellular,-1,1000 -Exchange,ser_L,Extracellular,-1,1000 -Exchange,val_L,Extracellular,-1,1000 -Exchange,gly,Extracellular,-1,1000 -Exchange,cys_L,Extracellular,-1,1000 -Exchange,ala_L,Extracellular,-1,1000 -Exchange,his_L,Extracellular,-1,1000 -Exchange,thr_L,Extracellular,-1,1000 -Exchange,gln_L,Extracellular,-1,1000 -Exchange,phe_L,Extracellular,-1,1000 -Exchange,tyr_L,Extracellular,-1,1000 -Exchange,arg_L,Extracellular,-1,1000 -Exchange,trp_L,Extracellular,-1,1000 -Exchange,eicostet,Extracellular,-1,1000 -Exchange,hdca,Extracellular,-1,1000 -Exchange,hdcea,Extracellular,-1,1000 -Exchange,lnlc,Extracellular,-1,1000 -Exchange,lnlnca,Extracellular,-1,1000 -Exchange,lnlncg,Extracellular,-1,1000 -Exchange,ocdca,Extracellular,-1,1000 -Exchange,ocdcea,Extracellular,-1,1000 -Exchange,thmmp,Extracellular,0,1000 -Exchange,thmtp,Extracellular,0,1000 -Exchange,ncam,Extracellular,0,1000 -Exchange,pnto_R,Extracellular,0,1000 -Exchange,pydxn,Extracellular,0,1000 -Exchange,pydx,Extracellular,0,1000 -Exchange,pydam,Extracellular,0,1000 -Exchange,btn,Extracellular,0,1000 -Exchange,fol,Extracellular,-10,1000 -Exchange,aqcobal,Extracellular,0,1000 -Exchange,vitd3,Extracellular,-1,1000 -Exchange,ascb_L,Extracellular,0,1000 -Exchange,retinol,Extracellular,-10,1000 -Exchange,retinal,Extracellular,-10,1000 -Exchange,ala_B,Extracellular,-1,1000 -Exchange,ala_D,Extracellular,-1,1000 +Exchange,asn_L,Extracellular,-1000,1 +Exchange,asp_L,Extracellular,-1000,1 +Exchange,glu_L,Extracellular,-1000,1 +Exchange,ile_L,Extracellular,-1000,1 +Exchange,leu_L,Extracellular,-1000,1 +Exchange,lys_L,Extracellular,-1000,1 +Exchange,met_L,Extracellular,-1000,1 +Exchange,pro_L,Extracellular,-1000,1 +Exchange,ser_L,Extracellular,-1000,1 +Exchange,val_L,Extracellular,-1000,1 +Exchange,gly,Extracellular,-1000,1 +Exchange,cys_L,Extracellular,-1000,1 +Exchange,ala_L,Extracellular,-1000,1 +Exchange,his_L,Extracellular,-1000,1 +Exchange,thr_L,Extracellular,-1000,1 +Exchange,gln_L,Extracellular,-1000,1 +Exchange,phe_L,Extracellular,-1000,1 +Exchange,tyr_L,Extracellular,-1000,1 +Exchange,arg_L,Extracellular,-1000,1 +Exchange,trp_L,Extracellular,-1000,1 +Exchange,eicostet,Extracellular,-1000,1 +Exchange,hdca,Extracellular,-1000,1 +Exchange,hdcea,Extracellular,-1000,1 +Exchange,lnlc,Extracellular,-1000,1 +Exchange,lnlnca,Extracellular,-1000,1 +Exchange,lnlncg,Extracellular,-1000,1 +Exchange,ocdca,Extracellular,-1000,1 +Exchange,ocdcea,Extracellular,-1000,1 +Exchange,thmmp,Extracellular,-1000,0 +Exchange,thmtp,Extracellular,-1000,0 +Exchange,ncam,Extracellular,-1000,0 +Exchange,pnto_R,Extracellular,-1000,0 +Exchange,pydxn,Extracellular,-1000,0 +Exchange,pydx,Extracellular,-1000,0 +Exchange,pydam,Extracellular,-1000,0 +Exchange,btn,Extracellular,-1000,0 +Exchange,fol,Extracellular,-1000,10 +Exchange,aqcobal,Extracellular,-1000,0 +Exchange,vitd3,Extracellular,-1000,1 +Exchange,ascb_L,Extracellular,-1000,0 +Exchange,retinol,Extracellular,-1000,10 +Exchange,retinal,Extracellular,-1000,10 +Exchange,ala_B,Extracellular,-1000,1 +Exchange,ala_D,Extracellular,-1000,1 Exchange,h2co3,Extracellular,-1000,1000 Exchange,h2o2,Extracellular,-1000,1000 Exchange,hco3,Extracellular,-1000,1000 -Exchange,orn,Extracellular,-1,1000 -Exchange,orn_D,Extracellular,-1,1000 +Exchange,orn,Extracellular,-1000,1 +Exchange,orn_D,Extracellular,-1000,1 Exchange,so4,Extracellular,-1000,1000 -Exchange,ribflv,Extracellular,-1,1000 -Exchange,Lcystin,Extracellular,-1,1000 \ No newline at end of file +Exchange,ribflv,Extracellular,-1000,1 +Exchange,Lcystin,Extracellular,-1000,1 diff --git a/main/data/boundary_rxns/smB_boundary_rxns.csv b/main/data/boundary_rxns/smB_boundary_rxns.csv index 0b08556e..9f0f9385 100644 --- a/main/data/boundary_rxns/smB_boundary_rxns.csv +++ b/main/data/boundary_rxns/smB_boundary_rxns.csv @@ -1,4 +1,4 @@ -Boundary,Abbreviation,Compartment,Minimum Reaction Rate,Maximum Reaction Rate +Reaction,Abbreviation,Compartment,Minimum Reaction Rate,Maximum Reaction Rate Exchange,glc_D,Extracellular,-100,1000 Exchange,fe2,Extracellular,-1000,1000 Exchange,gal,Extracellular,0,1000 @@ -67,4 +67,4 @@ Exchange,orn,Extracellular,-1,1000 Exchange,orn_D,Extracellular,-1,1000 Exchange,so4,Extracellular,-1000,1000 Exchange,ribflv,Extracellular,-1,1000 -Exchange,Lcystin,Extracellular,-1,1000 \ No newline at end of file +Exchange,Lcystin,Extracellular,-1,1000 From efbeed189da8d12c3babf875dda40149995692a8 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 5 Sep 2025 11:15:04 -0500 Subject: [PATCH 219/265] feat: provide `identifier_column` for dynamic splitting of gene expression data Signed-off-by: Josh Loecker --- main/como/utils.py | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/main/como/utils.py b/main/como/utils.py index fc8c9739..3a3d37ce 100644 --- a/main/como/utils.py +++ b/main/como/utils.py @@ -1,14 +1,12 @@ from __future__ import annotations -import asyncio import contextlib -import functools import io import sys from collections.abc import Iterator -from concurrent.futures import ThreadPoolExecutor from io import TextIOWrapper from pathlib import Path +from typing import Literal import numpy.typing as npt import pandas as pd @@ -61,30 +59,33 @@ def stringlist_to_list(stringlist: str | list[str]) -> list[str]: def split_gene_expression_data( expression_data: pd.DataFrame, + identifier_column: Literal["ensembl_gene_id", "entrez_gene_id"], recon_algorithm: Algorithm | None = None, - entrez_as_index: bool = True, + *, + ensembl_as_index: bool = True, ): """Split the gene expression data into single-gene and multiple-gene names. :param expression_data: The gene expression data to map + :param identifier_column: The column containing the gene identifiers, either 'ensembl_gene_id' or 'entrez_gene_id' :param recon_algorithm: The recon algorithm used to generate the gene expression data - :param entrez_as_index: Should the 'entrez_gene_id' column be set as the index + :param ensembl_as_index: Should the 'ensembl_gene_id' column be set as the index :return: """ expression_data.columns = [c.lower() for c in expression_data.columns] if recon_algorithm in {Algorithm.IMAT, Algorithm.TINIT}: expression_data.rename(columns={"combine_z": "active"}, inplace=True) - expression_data = expression_data[["entrez_gene_id", "active"]] - single_gene_names = expression_data[~expression_data["entrez_gene_id"].astype(str).str.contains("//")] - multiple_gene_names = expression_data[expression_data["entrez_gene_id"].astype(str).str.contains("//")] - split_gene_names = multiple_gene_names.assign(entrez_gene_id=multiple_gene_names["entrez_gene_id"].astype(str).str.split("///")).explode( - "entrez_gene_id" + expression_data = expression_data[[identifier_column, "active"]] + single_gene_names = expression_data[~expression_data[identifier_column].astype(str).str.contains("//")] + multiple_gene_names = expression_data[expression_data[identifier_column].astype(str).str.contains("//")] + split_gene_names = multiple_gene_names.assign(ensembl_gene_id=multiple_gene_names[identifier_column].astype(str).str.split("///")).explode( + identifier_column ) gene_expressions = pd.concat([single_gene_names, split_gene_names], axis=0, ignore_index=True) - if entrez_as_index: - gene_expressions.set_index("entrez_gene_id", inplace=True) + if ensembl_as_index: + gene_expressions.set_index(identifier_column, inplace=True) return gene_expressions @@ -135,6 +136,8 @@ async def _read_file( or scanpy.read_h5ad, depending on the filepath provided :return: None, or a pandas DataFrame or AnnData """ + if isinstance(path, (pd.DataFrame, sc.AnnData)): + return path if not path: return None @@ -159,7 +162,7 @@ async def _read_file( if h5ad_as_df: df = adata.to_df().T df.index.name = "gene_symbol" - df.reset_index(inplace=True) + df.reset_index(inplace=True, drop=False) return df return adata case _: From aac7bbd96e6c42d751010891e41a4747533cbf90 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 5 Sep 2025 11:18:11 -0500 Subject: [PATCH 220/265] feat: use async file reading Signed-off-by: Josh Loecker --- main/como/rnaseq_preprocess.py | 98 +++++++++++++++++++--------------- 1 file changed, 56 insertions(+), 42 deletions(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index b54c96f9..8a843c4b 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -1,6 +1,7 @@ from __future__ import annotations import asyncio +import functools import json import re import sys @@ -49,17 +50,16 @@ async def build_from_tab(cls, filepath: Path) -> _STARinformation: level=LogLevel.ERROR, ) - with filepath.open("r") as i_stream: - unmapped = i_stream.readline() - multimapping = i_stream.readline() - no_feature = i_stream.readline() - ambiguous = i_stream.readline() + async with aiofiles.open(filepath) as i_stream: + unmapped, multimapping, no_feature, ambiguous = await asyncio.gather( + *[i_stream.readline(), i_stream.readline(), i_stream.readline(), i_stream.readline()] + ) num_unmapped = [int(i) for i in unmapped.rstrip("\n").split("\t")[1:]] num_multimapping = [int(i) for i in multimapping.rstrip("\n").split("\t")[1:]] num_no_feature = [int(i) for i in no_feature.rstrip("\n").split("\t")[1:]] num_ambiguous = [int(i) for i in ambiguous.rstrip("\n").split("\t")[1:]] - remainder = await asyncio.to_thread(i_stream.read) + remainder = await i_stream.read() df = await _read_file(StringIO(remainder), sep="\t", header=None) df.columns = [ @@ -220,8 +220,9 @@ def _organize_gene_counts_files(data_dir: Path) -> list[_StudyMetrics]: async def _process_first_multirun_sample(strand_file: Path, all_counts_files: list[Path]): sample_count = pd.DataFrame() - for file in all_counts_files: - star_information = await _STARinformation.build_from_tab(file) + all_star_information: list[_STARinformation] = await asyncio.gather(*[_STARinformation.build_from_tab(file) for file in all_counts_files]) + + for star_information in all_star_information: strand_information = strand_file.read_text().rstrip("\n").lower() if strand_information not in ("none", "first_read_transcription_strand", "second_read_transcription_strand"): @@ -238,16 +239,16 @@ async def _process_first_multirun_sample(strand_file: Path, all_counts_files: li strand_information = "unstranded_rna_counts" run_counts = star_information.count_matrix[["ensembl_gene_id", strand_information]] - run_counts.columns = pd.Index(["ensembl_gene_id", "counts"]) + run_counts.columns = ["ensembl_gene_id", "counts"] sample_count = run_counts if sample_count.empty else sample_count.merge(run_counts, on=["ensembl_gene_id", "counts"], how="outer") # Set na values to 0 sample_count = sample_count.fillna(value="0") sample_count["counts"] = sample_count["counts"].astype(np.float64) - count_sums: pd.DataFrame = pd.DataFrame(sample_count.sum(axis=1, numeric_only=True)) - count_sums.insert(0, "ensembl_gene_id", sample_count["ensembl_gene_id"]) - count_sums.columns = pd.Index(["ensembl_gene_id", _sample_name_from_filepath(strand_file)]) + count_sums = sample_count.groupby("ensembl_gene_id", as_index=False)["counts"].mean() + count_sums["counts"] = np.ceil(count_sums["counts"].astype(np.uint32)) + count_sums.columns = ["ensembl_gene_id", _sample_name_from_filepath(strand_file)] return count_sums @@ -269,7 +270,7 @@ async def _process_standard_replicate(counts_file: Path, strand_file: Path, samp strand_information = "unstranded_rna_counts" sample_count = star_information.count_matrix[["ensembl_gene_id", strand_information]] - sample_count.columns = pd.Index(["ensembl_gene_id", sample_name]) + sample_count.columns = ["ensembl_gene_id", sample_name] return sample_count @@ -314,7 +315,8 @@ async def _create_sample_counts_matrix(metrics: _StudyMetrics) -> pd.DataFrame: # Remove run number "r\d+" from multi-run names if re.search(r"R\d+r1", metrics.sample_names[i]): new_sample_name = re.sub(r"r\d+", "", metrics.sample_names[i]) - counts.columns[i + 1 - adjusted_index] = new_sample_name + old_col_name = counts.columns[i + 1 - adjusted_index] + counts.rename(columns={old_col_name: new_sample_name}, inplace=True) return counts @@ -329,12 +331,11 @@ async def _write_counts_matrix( """Create a counts matrix file by reading gene counts table(s).""" study_metrics = _organize_gene_counts_files(data_dir=como_context_dir) counts: list[pd.DataFrame] = await asyncio.gather(*[_create_sample_counts_matrix(metric) for metric in study_metrics]) + rna_specific_sample_names = set(config_df.loc[config_df["library_prep"] == rna.value, "sample_name"].tolist()) - final_matrix = pd.DataFrame() - for count in counts: - final_matrix = count if final_matrix.empty else pd.merge(final_matrix, count, on="ensembl_gene_id", how="outer") - - rna_specific_sample_names = config_df.loc[config_df["library_prep"] == rna.value, "sample_name"].tolist() + final_matrix: pd.DataFrame = functools.reduce(lambda left, right: pd.merge(left, right, on="ensembl_gene_id", how="outer"), counts) + final_matrix.fillna(value=0, inplace=True) + final_matrix.iloc[:, 1:] = final_matrix.iloc[:, 1:].astype(np.uint64) final_matrix = final_matrix[["ensembl_gene_id", *rna_specific_sample_names]] output_counts_matrix_filepath.parent.mkdir(parents=True, exist_ok=True) @@ -418,6 +419,7 @@ async def _create_config_df( # noqa: C901 fragment_label = f"{context_name}_{label}_fragment_size.txt" frag_paths = [p for p in aux_lookup["fragment"].values() if p.name == fragment_label] + mean_frag = 100.0 if not frag_paths and prep != RNAType.TRNA.value: logger.warning(f"No fragment file for '{label}'; defaulting to 100 bp (needed for zFPKM).") mean_frag = 100.0 @@ -430,6 +432,7 @@ async def _create_config_df( # noqa: C901 counts = np.array([df["frag_count"].sum() for df in dfs]) means = np.array([(df["meanxcount"] / df["frag_count"].sum()).sum() for df in dfs]) mean_frag = float(np.average(means, weights=counts)) + rows.append( SampleConfiguration( sample_name=sample_id, @@ -621,7 +624,6 @@ async def _create_gene_info_file( """ async def read_counts(file: Path) -> list[str]: - print(f"Will read: '{file}'") data = await _read_file(file, h5ad_as_df=False) try: @@ -632,7 +634,7 @@ async def read_counts(file: Path) -> list[str]: ) except json.JSONDecodeError: _log_and_raise_error( - f"Got a JSO decode error for file '{counts_matrix_filepaths}'", + f"Got a JSON decode error for file '{counts_matrix_filepaths}'", error=ValueError, level=LogLevel.CRITICAL, ) @@ -645,11 +647,12 @@ async def read_counts(file: Path) -> list[str]: gene_data = await MyGene(cache=cache).query(items=list(genes), taxon=taxon, scopes="entrezgene") gene_info: pd.DataFrame = pd.DataFrame( data=None, - columns=pd.Index(data=["ensembl_gene_id", "gene_symbol", "entrez_gene_id", "size"]), - index=pd.Index(data=range(len(gene_data))), + columns=["ensembl_gene_id", "gene_symbol", "entrez_gene_id", "size"], + index=list(range(len(gene_data))), ) for i, data in enumerate(gene_data): - ensembl_ids = data.get("genomic_pos.ensemblgene", "-") + # ensembl_ids = data.get("genomic_pos.ensemblgene", "-") + ensembl_ids = data.get("genomic_pos.ensemblgene", pd.NA) if isinstance(ensembl_ids, list): ensembl_ids = ensembl_ids[0] @@ -658,14 +661,16 @@ async def read_counts(file: Path) -> list[str]: end_pos = data.get("genomic_pos.end", 0) end_pos: int = int(sum(end_pos) / len(end_pos)) if isinstance(end_pos, list) else int(end_pos) - gene_info.at[i, "gene_symbol"] = data.get("symbol", "-") - gene_info.at[i, "entrez_gene_id"] = data.get("entrezgene", "-") + gene_info.at[i, "gene_symbol"] = data.get("symbol", pd.NA) + gene_info.at[i, "entrez_gene_id"] = data.get("entrezgene", pd.NA) gene_info.at[i, "ensembl_gene_id"] = ensembl_ids gene_info.at[i, "size"] = end_pos - start_pos - gene_info = gene_info[((gene_info["entrez_gene_id"] != "-") & (gene_info["ensembl_gene_id"] != "-") & (gene_info["gene_symbol"] != "-"))] + gene_info = gene_info[((~gene_info["entrez_gene_id"].isna()) & (~gene_info["ensembl_gene_id"].isna()) & (~gene_info["gene_symbol"].isna()))] gene_info.sort_values(by="ensembl_gene_id", inplace=True) gene_info.dropna(inplace=True) + + output_filepath.parent.mkdir(parents=True, exist_ok=True) gene_info.to_csv(output_filepath, index=False) logger.success(f"Gene Info file written at '{output_filepath}'") @@ -700,7 +705,9 @@ async def _process( output_mrna_config_filepath: Path | None, output_trna_matrix_filepath: Path | None, output_mrna_matrix_filepath: Path | None, + *, cache: bool, + create_gene_info_only: bool, ): rna_types: list[tuple[RNAType, Path, Path]] = [] if output_trna_config_filepath: @@ -709,29 +716,31 @@ async def _process( rna_types.append((RNAType.MRNA, output_mrna_config_filepath, output_mrna_matrix_filepath)) # if provided, iterate through como-input specific directories - tasks = [] - for rna, output_config_filepath, output_matrix_filepath in rna_types: - tasks.append( - asyncio.create_task( - _process_como_input( - context_name=context_name, - output_config_filepath=output_config_filepath, - como_context_dir=como_context_dir, - output_counts_matrix_filepath=output_matrix_filepath, - rna=rna, + if not create_gene_info_only: + tasks = [] + for rna, output_config_filepath, output_matrix_filepath in rna_types: + tasks.append( + asyncio.create_task( + _process_como_input( + context_name=context_name, + output_config_filepath=output_config_filepath, + como_context_dir=como_context_dir, + output_counts_matrix_filepath=output_matrix_filepath, + rna=rna, + ) ) ) - ) - await asyncio.gather(*tasks) + await asyncio.gather(*tasks) # create the gene info filepath based on provided data - input_files = [] if input_matrix_filepath: input_files.extend(input_matrix_filepath) - output_trna_matrix_filepath and input_files.append(output_trna_matrix_filepath) - output_mrna_matrix_filepath and input_files.append(output_mrna_matrix_filepath) + if output_trna_matrix_filepath: + input_files.append(output_trna_matrix_filepath) + if output_mrna_matrix_filepath: + input_files.append(output_mrna_matrix_filepath) await _create_gene_info_file( counts_matrix_filepaths=input_files, @@ -754,6 +763,8 @@ async def rnaseq_preprocess( cache: bool = True, log_level: LogLevel | str = LogLevel.INFO, log_location: str | TextIOWrapper = sys.stderr, + *, + create_gene_info_only: bool = False, ) -> None: """Preprocesses RNA-seq data for downstream analysis. @@ -773,6 +784,7 @@ async def rnaseq_preprocess( :param cache: Should HTTP requests be cached :param log_level: The logging level :param log_location: The logging location + :param create_gene_info_only: If True, only create the gene info file and skip general preprocessing steps """ _set_up_logging(level=log_level, location=log_location) @@ -780,6 +792,7 @@ async def rnaseq_preprocess( if como_context_dir: como_context_dir = como_context_dir.resolve() + input_matrix_filepath = [i.resolve() for i in _listify(input_matrix_filepath)] if input_matrix_filepath else None output_trna_metadata_filepath = output_trna_metadata_filepath.resolve() if output_trna_metadata_filepath else None output_mrna_metadata_filepath = output_mrna_metadata_filepath.resolve() if output_mrna_metadata_filepath else None @@ -797,6 +810,7 @@ async def rnaseq_preprocess( output_trna_matrix_filepath=output_trna_count_matrix_filepath, output_mrna_matrix_filepath=output_mrna_count_matrix_filepath, cache=cache, + create_gene_info_only=create_gene_info_only, ) From d1dae99ee9a41f1e2286f2a21c8555030ac5bfdc Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 5 Sep 2025 11:18:48 -0500 Subject: [PATCH 221/265] refactor!: rename `graph` to `plot` BREAKING-CHANGE: use `como.plot` instead of `como.graph` Signed-off-by: Josh Loecker --- main/como/__init__.py | 1 + main/como/graph/__init__.py | 50 ------------------------------------- main/como/plot/__init__.py | 0 3 files changed, 1 insertion(+), 50 deletions(-) delete mode 100644 main/como/graph/__init__.py create mode 100644 main/como/plot/__init__.py diff --git a/main/como/__init__.py b/main/como/__init__.py index c84ef56e..cba3d35f 100644 --- a/main/como/__init__.py +++ b/main/como/__init__.py @@ -1,3 +1,4 @@ +from como import plot from como.data_types import AdjustmentMethod, Algorithm, CobraCompartments, FilteringTechnique, LogLevel, Solver from como.utils import stringlist_to_list diff --git a/main/como/graph/__init__.py b/main/como/graph/__init__.py deleted file mode 100644 index 7594db2f..00000000 --- a/main/como/graph/__init__.py +++ /dev/null @@ -1,50 +0,0 @@ -from pathlib import Path - -import pandas as pd -import seaborn as sns -from loguru import logger -from matplotlib import pyplot as plt - - -def z_score_distribution( - df: pd.DataFrame, - title: str, - output_filepath: Path, -): - """Graph a z-score distribution. - - :param df: The z-score data to graph - :param title: Title to add to graph - :param output_filepath: Output PNG filepath location - :return: None - """ - if output_filepath.suffix not in {".png", ".pdf", ".svg"}: - logger.warning( - f"Expected .png, .pdf, or .svg suffix for output_png_filepath, got {output_filepath.suffix}. " - f"Defaulting to .pdf" - ) - output_filepath = output_filepath.with_suffix(".pdf") - logger.trace("Graphing z-score distribution") - output_filepath.parent.mkdir(parents=True, exist_ok=True) - output_filepath.unlink(missing_ok=True) - - plt.figure(figsize=(10, 6)) - - if len(df["source"].unique()) == 1: - ax = sns.histplot(df, x="zscore", bins=100, kde=True) - sns.rugplot(df, x="zscore", ax=ax) - else: - sns.histplot(df, x="zscore", hue="source", bins=100, kde=True, element="step") - plt.legend(loc="upper right", frameon=False, title=None) - - plt.title(title) - plt.xlabel("Z-score") - plt.ylabel("Frequency") - plt.xticks(fontsize=12) - plt.yticks(fontsize=12) - plt.gca().spines["top"].set_visible(False) - plt.gca().spines["right"].set_visible(False) - plt.tight_layout() - plt.savefig(output_filepath) - plt.close() - logger.success(f"Saved z-score distribution graph to '{output_filepath}'") diff --git a/main/como/plot/__init__.py b/main/como/plot/__init__.py new file mode 100644 index 00000000..e69de29b From b7983c3b95b39ee29af64a61cbf1ed9d2f06f475 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 5 Sep 2025 11:19:22 -0500 Subject: [PATCH 222/265] chore: remove trailing underscore; do not write index Signed-off-by: Josh Loecker --- main/como/combine_distributions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index 9717eca1..5311fd9b 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -225,7 +225,7 @@ async def _begin_combining_distributions( matrix=matrix[[GeneIdentifier.ENSEMBL_GENE_ID.value, *batch.sample_names]], source=source, output_combined_matrix_filepath=( - output_filepaths[source.value].parent / f"{context_name}_{source.value}_batch{batch.batch_num}_combined_z_distribution_.csv" + output_filepaths[source.value].parent / f"{context_name}_{source.value}_batch{batch.batch_num}_combined_z_distribution.csv" ), output_figure_dirpath=output_figure_dirpath, weighted_z_floor=weighted_z_floor, @@ -257,7 +257,7 @@ async def _begin_combining_distributions( weight=source_weights[source.value], ) ) - merged_source_results.to_csv(output_filepaths[source.value]) + merged_source_results.to_csv(output_filepaths[source.value], index=False) logger.success(f"Wrote z-scores for source '{source.value}' in context '{context_name}' to '{output_filepaths[source.value]}'") logger.trace(f"Combining z-score distributions for all sources in context '{context_name}'") From 009fbb23c6b7d38badf4f1d1d02d459d6976f4ba Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 5 Sep 2025 11:20:31 -0500 Subject: [PATCH 223/265] feat: add identifier column check for gene expression data processing Signed-off-by: Josh Loecker --- main/como/create_context_specific_model.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 8818280e..6ac2327e 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -6,6 +6,7 @@ from collections.abc import Sequence from io import TextIOWrapper from pathlib import Path +from typing import Literal, cast import cobra import numpy as np @@ -263,7 +264,18 @@ async def _map_expression_to_reaction( These rules should be defined in the general genome-scale metabolic model """ - gene_activity = split_gene_expression_data(await _read_file(gene_expression_file), recon_algorithm=recon_algorithm) + expression_data = await _read_file(gene_expression_file) + identifier_column = next((col for col in ("entrez_gene_id", "ensembl_gene_id") if col in expression_data.columns), "") + + if not identifier_column: + raise ValueError( + f"At least one column of 'entrez_gene_id' or 'ensembl_gene_id' could not be found in the gene expression file '{gene_expression_file}'" + ) + gene_activity = split_gene_expression_data( + expression_data, + identifier_column=cast(Literal["ensembl_gene_id", "entrez_gene_id"], identifier_column), + recon_algorithm=recon_algorithm, + ) reaction_expression = collections.OrderedDict() # fmt: off @@ -281,19 +293,19 @@ async def _map_expression_to_reaction( rxn: cobra.Reaction gene_reaction_rule = rxn.gene_reaction_rule - if gene_reaction_rule == "": + if not gene_reaction_rule: continue gene_ids = set(re.findall(r"\d+", gene_reaction_rule)) reaction_expression[rxn.id] = default_expression for gene_id in gene_ids: - activity = f"{gene_activity.at[gene_id, 'active']}" if gene_id in gene_activity.index else f"{default_expression!s}" + activity = gene_activity.at[gene_id, "active"] if gene_id in gene_activity.index else f"{default_expression!s}" # replace gene_id with activity, using optional whitespace before and after the gene id # Do not replace the whitespace (if it exists) before and after the gene ID gene_reaction_rule = re.sub(pattern=rf"\b{gene_id}\b", repl=activity, string=gene_reaction_rule) try: - # We are using eval here because ast.literal_eval is unable to process an evaluable such as `max(-4, -4)` + # We are using eval here because ast.literal_eval is unable to process an evaluable such as `max(-4, 0, 1)` # This isn't ideal, but ultimately the only other option is writing and maintaining a custom parsing engine, which is too much work evaluable_gene_rule = _gene_rule_logical(gene_reaction_rule).replace("{", "(").replace("}", ")") reaction_expression[rxn.id] = eval(evaluable_gene_rule) # noqa: S307 From 0a7c0a60b0206059c81c3a22024181ae1edaa4f0 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 5 Sep 2025 11:20:50 -0500 Subject: [PATCH 224/265] fix: replace '-' with pd.NA in drug target genes DataFrame Signed-off-by: Josh Loecker --- main/como/knock_out_simulation.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/main/como/knock_out_simulation.py b/main/como/knock_out_simulation.py index fe96c784..9e4e578a 100644 --- a/main/como/knock_out_simulation.py +++ b/main/como/knock_out_simulation.py @@ -74,7 +74,7 @@ def knock_out_simulation( drug_db = drug_db[drug_db["moa"].str.lower().str.contains("inhibitor")] drug_target_genes = pd.DataFrame(columns=["Gene ID"]) drug_target_genes["Gene ID"] = drug_db["Gene ID"].astype(str) - drug_target_genes.replace("-", np.nan, inplace=True) + drug_target_genes.replace("-", pd.NA, inplace=True) drug_target_genes.dropna(axis=0, inplace=True) drug_target_genes.to_csv(inhibitors_filepath, header=True, sep="\t", index=False) print(f"Inhibitors file written to: {inhibitors_filepath}") @@ -280,8 +280,7 @@ def main(argv): parser = argparse.ArgumentParser( prog="knock_out_simulation.py", description="This script is responsible for mapping drug targets in metabolic models, performing knock out simulations, and comparing simulation results with disease genes. It also identified drug targets and repurposable drugs.", - epilog="For additional help, please post questions/issues in the MADRID GitHub repo at " - "https://github.com/HelikarLab/COMO", + epilog="For additional help, please post questions/issues in the MADRID GitHub repo at https://github.com/HelikarLab/COMO", ) parser.add_argument( "-m", From 3468625d84cd97fb1c42394418b75c3f03211e6e Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 5 Sep 2025 11:21:49 -0500 Subject: [PATCH 225/265] style: ruff formatting Signed-off-by: Josh Loecker --- main/como/merge_xomics.py | 36 +++++++++++++----------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index a25f8e78..b613b92a 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -110,9 +110,7 @@ def _merge_logical_table(df: pd.DataFrame): df.dropna(subset=["entrez_gene_id"], inplace=True) df["entrez_gene_id"] = df["entrez_gene_id"].astype(str).str.replace(" /// ", "//").astype(str) - id_list: list[str] = df.loc[ - ~df["entrez_gene_id"].str.contains("//"), "entrez_gene_id" - ].tolist() # Collect "single" ids, like "123" + id_list: list[str] = df.loc[~df["entrez_gene_id"].str.contains("//"), "entrez_gene_id"].tolist() # Collect "single" ids, like "123" multiple_entrez_ids: list[str] = df.loc[ df["entrez_gene_id"].str.contains("//"), "entrez_gene_id" ].tolist() # Collect "double" ids, like "123//456" @@ -291,9 +289,7 @@ async def _merge_xomics( logger.trace(f"Shape of merged data before merging logical tables: {merge_data.shape}") if merge_data.empty: - logger.warning( - f"No data is available for the '{context_name}' context. If this is intentional, ignore this error." - ) + logger.warning(f"No data is available for the '{context_name}' context. If this is intentional, ignore this error.") return {} merge_data = _merge_logical_table(merge_data) @@ -306,9 +302,7 @@ async def _merge_xomics( if adjust_for_missing_sources: # Subtract 1 from requirement per missing source logger.trace("Adjusting for missing data sources") merge_data.loc[:, "required"] = merge_data[expression_list].apply( - lambda x: expression_requirement - (num_sources - x.count()) - if (expression_requirement - (num_sources - x.count()) > 0) - else 1, + lambda x: expression_requirement - (num_sources - x.count()) if (expression_requirement - (num_sources - x.count()) > 0) else 1, axis=1, ) else: # Do not adjust for missing sources @@ -354,10 +348,10 @@ async def _update_missing_data(input_matrices: _InputMatrices, taxon_id: int) -> results = await asyncio.gather( *[ # Using 'is not None' is required because the truth value of a Dataframe is ambiguous - get_missing_gene_data(values=input_matrices.trna, taxon_id=taxon_id) if input_matrices.trna is not None else asyncio.sleep(0), # noqa: E501 - get_missing_gene_data(values=input_matrices.mrna, taxon_id=taxon_id) if input_matrices.mrna is not None else asyncio.sleep(0), # noqa: E501 - get_missing_gene_data(values=input_matrices.scrna, taxon_id=taxon_id) if input_matrices.scrna is not None else asyncio.sleep(0), # noqa: E501 - get_missing_gene_data(values=input_matrices.proteomics, taxon_id=taxon_id) if input_matrices.proteomics is not None else asyncio.sleep(0), # noqa: E501 + get_missing_gene_data(values=input_matrices.trna, taxon_id=taxon_id) if input_matrices.trna is not None else asyncio.sleep(0), + get_missing_gene_data(values=input_matrices.mrna, taxon_id=taxon_id) if input_matrices.mrna is not None else asyncio.sleep(0), + get_missing_gene_data(values=input_matrices.scrna, taxon_id=taxon_id) if input_matrices.scrna is not None else asyncio.sleep(0), + get_missing_gene_data(values=input_matrices.proteomics, taxon_id=taxon_id) if input_matrices.proteomics is not None else asyncio.sleep(0), ] ) # fmt: on @@ -376,10 +370,7 @@ async def _update_missing_data(input_matrices: _InputMatrices, taxon_id: int) -> # fmt: on logger.trace(f"Merging conversion data for {matrix_name}, existing id column is: {existing_data}") input_matrices[matrix_name] = ( - input_matrices[matrix_name] - .merge(conversion, how="left", on=[existing_data]) - .dropna() - .reset_index(drop=True) + input_matrices[matrix_name].merge(conversion, how="left", on=[existing_data]).dropna().reset_index(drop=True) ) logger.debug("Updated missing genomic data") @@ -577,8 +568,8 @@ async def merge_xomics( # noqa: C901 # fmt: off source_data = { - SourceTypes.TRNA: (trna_matrix_or_filepath, trna_boolean_matrix_or_filepath, trna_metadata_filepath_or_df, output_trna_activity_filepath), # noqa: E501 - SourceTypes.MRNA: (mrna_matrix_or_filepath, mrna_boolean_matrix_or_filepath, mrna_metadata_filepath_or_df, output_mrna_activity_filepath), # noqa: E501 + SourceTypes.TRNA: (trna_matrix_or_filepath, trna_boolean_matrix_or_filepath, trna_metadata_filepath_or_df, output_trna_activity_filepath), + SourceTypes.MRNA: (mrna_matrix_or_filepath, mrna_boolean_matrix_or_filepath, mrna_metadata_filepath_or_df, output_mrna_activity_filepath), SourceTypes.SCRNA: (scrna_matrix_or_filepath, scrna_boolean_matrix_or_filepath, scrna_metadata_filepath_or_df, output_scrna_activity_filepath), # noqa: E501 SourceTypes.PROTEOMICS: (proteomic_matrix_or_filepath, proteomic_boolean_matrix_or_filepath, proteomic_metadata_filepath_or_df, output_proteomic_activity_filepath), # noqa: E501 } @@ -604,10 +595,8 @@ async def merge_xomics( # noqa: C901 level=LogLevel.ERROR, ) - if expression_requirement < 1: - logger.warning( - f"Expression requirement must be at least 1! Setting to the minimum of 1 now. Got: {expression_requirement}" - ) + if not expression_requirement or expression_requirement < 1: + logger.warning(f"Expression requirement must be at least 1! Setting to the minimum of 1 now. Got: {expression_requirement}") expression_requirement = 1 if expression_requirement is None: @@ -663,6 +652,7 @@ async def merge_xomics( # noqa: C901 ) # build scrna items + scrna_matrix: pd.DataFrame | None scrna_boolean_matrix: pd.DataFrame | None scrna_metadata: pd.DataFrame | None From 6561c24a7aee528da65cc7e106ce5f5b8f6bdee0 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 5 Sep 2025 11:22:12 -0500 Subject: [PATCH 226/265] refactor: use pd.NA instead of checking "-" Signed-off-by: Josh Loecker --- main/como/proteomics_gen.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/main/como/proteomics_gen.py b/main/como/proteomics_gen.py index dd50a75d..102490ba 100644 --- a/main/como/proteomics_gen.py +++ b/main/como/proteomics_gen.py @@ -45,7 +45,7 @@ async def load_gene_symbol_map(gene_symbols: list[str], entrez_map: Path | None input_db=Input.GENE_SYMBOL, output_db=[Output.GENE_ID, Output.ENSEMBL_GENE_ID], ) - df.loc[df["gene_id"] == "-", ["gene_id"]] = np.nan + df.loc[df["gene_id"].isna(), ["gene_id"]] = np.nan df.to_csv(entrez_map, index_label="gene_symbol") return df[~df.index.duplicated()] @@ -134,9 +134,7 @@ def load_empty_dict(): inquiry_full_path = config.data_dir / "config_sheets" / filename if not inquiry_full_path.exists(): - _log_and_raise_error( - f"Error: file not found {inquiry_full_path}", error=FileNotFoundError, level=LogLevel.ERROR - ) + _log_and_raise_error(f"Error: file not found {inquiry_full_path}", error=FileNotFoundError, level=LogLevel.ERROR) filename = f"Proteomics_{context_name}.csv" full_save_filepath = config.result_dir / context_name / "proteomics" / filename @@ -146,10 +144,7 @@ def load_empty_dict(): return context_name, data else: - logger.warning( - f"Proteomics gene expression file for {context_name} was not found at {full_save_filepath}. " - f"Is this intentional?" - ) + logger.warning(f"Proteomics gene expression file for {context_name} was not found at {full_save_filepath}. Is this intentional?") return load_empty_dict() From bf5606943a382ab8c966745ff4e97a317f3584ef Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 5 Sep 2025 11:22:36 -0500 Subject: [PATCH 227/265] fix: only drop NA values from ensembl_gene_id, not entire dataframe Signed-off-by: Josh Loecker --- main/como/rnaseq_gen.py | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index e2e988d4..d4ba7335 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -159,7 +159,7 @@ async def _build_matrix_results( :param taxon: The NCBI Taxon ID :return: A dataclass `ReadMatrixResults` """ - matrix.dropna(inplace=True) + matrix.dropna(subset="ensembl_gene_id", inplace=True) conversion = await ensembl_to_gene_id_and_symbol(ids=matrix["ensembl_gene_id"].tolist(), taxon=taxon) conversion["ensembl_gene_id"] = conversion["ensembl_gene_id"].str.split(",") conversion = conversion.explode("ensembl_gene_id") @@ -184,11 +184,12 @@ async def _build_matrix_results( # Only include Entrez and Ensembl Gene IDs that are present in `gene_info` matrix["entrez_gene_id"] = matrix["entrez_gene_id"].str.split("//") matrix = matrix.explode("entrez_gene_id") - matrix = matrix.replace(to_replace="-", value=pd.NA).dropna() + # matrix = matrix.replace(to_replace="-", value=pd.NA) + matrix.dropna(subset="entrez_gene_id", inplace=True) matrix["entrez_gene_id"] = matrix["entrez_gene_id"].astype(int) gene_info = gene_info_migrations(gene_info) - gene_info = gene_info.replace(to_replace="-", value=pd.NA).dropna() + # gene_info = gene_info.replace(to_replace="-", value=pd.NA) gene_info["entrez_gene_id"] = gene_info["entrez_gene_id"].astype(int) counts_matrix = matrix.merge( @@ -244,9 +245,10 @@ def _calculate_fpkm(metrics: NamedMetrics, scale: int = 1e6) -> NamedMetrics: """Calculate the Fragments Per Kilobase of transcript per Million mapped reads (FPKM) for each sample in the metrics dictionary.""" for study in metrics: matrix_values = [] + for sample in range(metrics[study].num_samples): layout = metrics[study].layout[sample] - count_matrix: pd.DataFrame = metrics[study].count_matrix.iloc[:, sample].values.astype(np.float32) + count_matrix: npt.NDArray[np.float32] = metrics[study].count_matrix.iloc[:, sample].values gene_lengths = ( metrics[study].fragment_lengths[sample].astype(np.float32) if layout == LayoutMethod.paired_end @@ -302,6 +304,7 @@ def _zfpkm_calculation( Stabilize the variance in the data to make the distribution more symmetric; this is helpful for Gaussian fitting Kernel Density Estimation (kde) + - SciKit Learn: https://scikit-learn.org/stable/modules/density.html - Non-parametric method to estimate the probability density function (PDF) of a random variable - Estimates the distribution of log2-transformed FPKM values - Bandwidth parameter controls the smoothness of the density estimate @@ -340,8 +343,11 @@ def _zfpkm_calculation( a threshold for calling a gene as "active" and/or "expressed" : https://doi.org/10.1186/1471-2164-14-778 """ - values = column.values - refit: KernelDensity = KernelDensity(kernel="gaussian", bandwidth=bandwidth).fit(values.reshape(-1, 1)) # type: ignore + values: npt.NDArray = column.values + # replace na values with 0 + values = np.nan_to_num(values, nan=0.0) + refit: KernelDensity = KernelDensity(kernel="gaussian", bandwidth=bandwidth) + refit.fit(values.reshape(-1, 1)) x_range = np.linspace(values.min(), values.max(), 2000) density = np.exp(refit.score_samples(x_range.reshape(-1, 1))) @@ -702,9 +708,9 @@ async def _process( rnaseq_matrix: pd.DataFrame = await _read_file(rnaseq_matrix_filepath) if rnaseq_matrix_filepath.suffix == ".h5ad": conversion = await gene_symbol_to_ensembl_and_gene_id(symbols=rnaseq_matrix["gene_symbol"].tolist(), taxon=taxon) - conversion.reset_index(inplace=True) + conversion.reset_index(inplace=True, drop=False) rnaseq_matrix = rnaseq_matrix.merge(conversion, how="left", on="gene_symbol") - rnaseq_matrix.replace(to_replace=pd.NA, value="-") + # rnaseq_matrix = rnaseq_matrix.replace(to_replace=pd.NA, value="-") filtering_options = _FilteringOptions( replicate_ratio=replicate_ratio, @@ -916,6 +922,17 @@ async def rnaseq_gen( # noqa: C901 level=LogLevel.ERROR, ) + metadata_df["fragment_length"] = metadata_df["fragment_length"].astype(np.float32) + metadata_df = metadata_df.groupby("sample_name", as_index=False).agg( + { + "sample_name": "first", + "fragment_length": "mean", + "layout": "first", + "strand": "first", + "study": "first", + "library_prep": "first", + } + ) logger.debug(f"Starting '{context_name}'") await _process( context_name=context_name, From dc324d5d4121c6e40fdb70c9fee115a367086857 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 5 Sep 2025 11:23:00 -0500 Subject: [PATCH 228/265] feat: added function to build heatmap of conditions vs pathways Signed-off-by: Josh Loecker --- main/como/plot/heatmap.py | 101 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 main/como/plot/heatmap.py diff --git a/main/como/plot/heatmap.py b/main/como/plot/heatmap.py new file mode 100644 index 00000000..cfa21c64 --- /dev/null +++ b/main/como/plot/heatmap.py @@ -0,0 +1,101 @@ +from __future__ import annotations + +import math +from pathlib import Path + +import matplotlib.colors as mcolors +import matplotlib.pyplot as plt +import numpy as np +import pandas as pd +import seaborn as sns +from matplotlib.ticker import FixedLocator + + +def condition_vs_pathway( + data: pd.DataFrame, + save_filepath: Path | None = None, + *, + copy_df: bool = False, + exclude_zero_flux_pathways: bool = False, +) -> plt.Figure: + """Build a heatmap of fluxes through pathways across conditions. + + :param data: Index values are conditions, column names are pathways + :param save_filepath: If provided, the resulting figure will be saved to this location + :param copy_df: Should the incoming dataframe be copied to prevent modifications to data? + :param exclude_zero_flux_pathways: Should pathways that have 0 flux across all rows be excluded? + + :return: The resulting `matpotlib.pyplt.Figure` object + """ + plot_df: pd.DataFrame = data.copy() if copy_df else data + plot_df = plot_df.astype(np.float32) + fig = plt.figure(figsize=(100, 40), dpi=175) + + if exclude_zero_flux_pathways: + # Select pathways that have at least one non-zero value + plot_df = plot_df.loc[:, plot_df.where(plot_df != 0).any(axis=0)] + + # Identify the second largest (pos or neg) value + # This is needed in order to set the upper & lower bounds for the graph, excluding +/- 1000-flux values + plot_df[plot_df > 1000] = 1001 + plot_df[plot_df < -1000] = -1001 + second_largest_positive = plot_df[plot_df > 0].stack().drop_duplicates().nlargest(2).iloc[-1] + second_largest_negative = plot_df[plot_df < 0].stack().drop_duplicates().nsmallest(2).iloc[-1] + vmax = max(abs(second_largest_negative), second_largest_positive) + + # Convert tick marks to reasonable values: + # max tick < 100: round to 10s place + # max tick < 1_000: round to 100s place + # max tick < 10_000: round to 1_000s place + base = 10 if vmax < 100 else 100 if vmax < 10_000 else 1000 + vmax_root = math.ceil(vmax / base) * base + + # Create 5 evenly spaced ticks along the legend + ticks = np.linspace(-vmax_root, vmax_root, 5) + + # Generate legend gradient + norm = mcolors.TwoSlopeNorm(vmin=-vmax_root, vcenter=0, vmax=vmax_root) + + # If a value falls outside of `vmax_root`, set it to the following colors + cmap = plt.get_cmap("coolwarm").copy() + cmap.set_over("#660033") + cmap.set_under("#000099") + + ax: plt.Axes = sns.heatmap( + data=plot_df, + linewidths=1.0, + linecolor="#686868", + center=0, + yticklabels=True, + xticklabels=True, + norm=norm, + cmap=cmap, + cbar_kws={"extend": "both", "label": f"Flux ratio (clipped at ±{vmax:.0f})"}, + ) + + plt.title("Metabolic Model Flux Sum through Pathways", fontsize=100) + + plt.xlabel("Pathway", fontsize=80) + ax.tick_params(axis="x", which="major", labelsize=55, labelrotation=90) + + plt.ylabel("Condition", fontsize=85) + ax.tick_params(axis="y", which="major", labelsize=55, labelrotation=0) + + cbar = ax.collections[0].colorbar + cbar.set_ticks(ticks) + cbar.ax.yaxis.set_major_locator(FixedLocator(ticks)) + cbar.update_ticks() + + # Add extended triangles that are detached from the colorbar (prevents very large pos/neg values from blowing out the legend) + cbar.ax.text(0.5, 1.06, "> +1000", ha="center", va="bottom", transform=cbar.ax.transAxes, fontsize=40) + cbar.ax.text(0.5, -0.06, "< -1000", ha="center", va="top", transform=cbar.ax.transAxes, fontsize=40) + cbar.ax.tick_params(labelsize=40) + cbar.set_label("Flux", rotation=270, labelpad=40) + + fig.tight_layout(h_pad=0.85) + + if save_filepath: + save_filepath.parent.mkdir(parents=True, exist_ok=True) + fig.savefig(save_filepath, transparent=False, bbox_inches="tight") + + return fig From 74d883db1fd49fa63ff60545d3911ea7ba7e0f38 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 5 Sep 2025 11:23:16 -0500 Subject: [PATCH 229/265] feat: added function to plot z score distribution Signed-off-by: Josh Loecker --- main/como/plot/z_score.py | 47 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 main/como/plot/z_score.py diff --git a/main/como/plot/z_score.py b/main/como/plot/z_score.py new file mode 100644 index 00000000..0822e63a --- /dev/null +++ b/main/como/plot/z_score.py @@ -0,0 +1,47 @@ +from pathlib import Path + +import pandas as pd +import seaborn as sns +from loguru import logger +from matplotlib import pyplot as plt + + +def z_score_distribution( + df: pd.DataFrame, + title: str, + output_filepath: Path, +): + """Graph a z-score distribution. + + :param df: The z-score data to graph + :param title: Title to add to graph + :param output_filepath: Output PNG filepath location + :return: None + """ + if output_filepath.suffix not in {".png", ".pdf", ".svg"}: + logger.warning(f"Expected .png, .pdf, or .svg suffix for output_png_filepath, got {output_filepath.suffix}. Defaulting to .pdf") + output_filepath = output_filepath.with_suffix(".pdf") + logger.trace("Graphing z-score distribution") + output_filepath.parent.mkdir(parents=True, exist_ok=True) + output_filepath.unlink(missing_ok=True) + + plt.figure(figsize=(10, 6)) + + if len(df["source"].unique()) == 1: + ax = sns.histplot(df, x="zscore", bins=100, kde=True) + sns.rugplot(df, x="zscore", ax=ax) + else: + sns.histplot(df, x="zscore", hue="source", bins=100, kde=True, element="step") + plt.legend(loc="upper right", frameon=False, title=None) + + plt.title(title) + plt.xlabel("Z-score") + plt.ylabel("Frequency") + plt.xticks(fontsize=12) + plt.yticks(fontsize=12) + plt.gca().spines["top"].set_visible(False) + plt.gca().spines["right"].set_visible(False) + plt.tight_layout() + plt.savefig(output_filepath) + plt.close() + logger.success(f"Saved z-score distribution graph to '{output_filepath}'") From b55215d21483aa4854385506b9679be3006b62ea Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 5 Sep 2025 11:24:03 -0500 Subject: [PATCH 230/265] feat: added `pipelines` module to make using utilities easier Signed-off-by: Josh Loecker --- main/como/pipelines/__init__.py | 0 .../pipelines/build_condition_heatmaps.py | 290 ++++++++++++++++++ 2 files changed, 290 insertions(+) create mode 100644 main/como/pipelines/__init__.py create mode 100644 main/como/pipelines/build_condition_heatmaps.py diff --git a/main/como/pipelines/__init__.py b/main/como/pipelines/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/main/como/pipelines/build_condition_heatmaps.py b/main/como/pipelines/build_condition_heatmaps.py new file mode 100644 index 00000000..a0161a45 --- /dev/null +++ b/main/como/pipelines/build_condition_heatmaps.py @@ -0,0 +1,290 @@ +"""Create heatmaps of conditions vs pathway flux. + +This pipeline will generate heatmaps showing the flux through various pathways +""" + +from __future__ import annotations + +import concurrent.futures +from collections import defaultdict +from functools import partial +from pathlib import Path + +import aiofiles.os +import aiofiles.ospath +import cobra +import matplotlib.pyplot as plt +import numpy as np +import numpy.typing as npt +import orjson +import pandas as pd +from pandas._libs.missing import NAType + +from como.plot.heatmap import condition_vs_pathway + + +async def afind_possible_model_filepaths(search_dir: Path) -> list[Path]: + """Asynchronously find potential files that could be constraint-based metabolic models. + + :param search_dir: The directory to search for models. + :return: Potential filepaths that could be loaded as a `cobra.Model` object + """ + return [f for f in list(await asyncio.to_thread(search_dir.rglob, pattern="*")) if f.suffix in {".mat", ".json", ".sbml", ".xml"}] + + +def find_possible_model_filepaths(search_dir: Path) -> list[Path]: + """Find potential files that could be constraint-based metabolic models. + + :param search_dir: The directory to search for models. + :return: Potential filepaths that could be loaded as a `cobra.Model` object + """ + return [f for f in search_dir.rglob("*") if f.suffix in {".mat", ".json", ".sbml", ".xml"}] + + +async def ais_filepath_a_model(filepath: Path) -> cobra.Model | None: + """Asynchronously evaluate if a given filepath can be read as a `cobra.Model`. + + :param filepath: The filepath to read + :return a `cobra.Model` object if the file can be read, otherwise None + """ + suffix = filepath.suffix.lower() + if suffix == ".mat": + return await asyncio.to_thread(cobra.io.load_matlab_model, infile_path=filepath) + elif suffix in {".xml", ".sbml"}: + return await asyncio.to_thread(cobra.io.read_sbml_model, filename=filepath) + elif suffix in {".yaml", ".yml"}: + async with aiofiles.open(filepath) as i_stream: + content = await i_stream.read() + return cobra.io.from_yaml(content) + elif suffix == ".json": + async with aiofiles.open(filepath) as i_stream: + content = await i_stream.read() + data = orjson.loads(content) + return cobra.io.model_from_dict(data) + return None + + +def get_cobra_model_if_valid(filepath: Path) -> cobra.Model | None: + """Evaluate if a given filepath can be read as a `cobra.Model`. + + :param filepath: The filepath to read + :return a `cobra.Model` object if the file can be read, otherwise None + """ + if filepath.suffix == ".json": + return cobra.io.load_json_model(filepath) + elif filepath.suffix == ".mat": + return cobra.io.load_matlab_model(filepath) + elif filepath.suffix in {".yaml", ".yml"}: + return cobra.io.load_yaml_model(filepath) + elif filepath.suffix in {".xml", ".sbml"}: + return cobra.io.read_sbml_model(filepath) + return None + + +def get_model_flux(model: cobra.Model, objective: str = "biomass_maintenance", solver: str = "gurobi") -> pd.Series: + """Get the flux through a CBMM. + + :param model: A `cobra.Model` object + :param objective: The objective function to optimize + :param solver: The solver to use + :return: A pandas Series of reaction fluxes indexed by reaction ID + """ + model.objective = objective + model.solver = solver + solution = model.optimize() + return solution.fluxes + + +def get_many_model_flux( + models: list[cobra.Model], + objective: str = "biomass_maintenance", + solver: str = "gurobi", + cores: int = 4, + process_pool: concurrent.futures.ProcessPoolExecutor | None = None, + colnames: list[str] | None = None, + na_value: NAType | int | float = NAType, +) -> pd.DataFrame: + """Get the flux through many CBMMs. + + :param models: A list of `cobra.Model` objects + :param objective: The objective function to optimize + :param solver: The solver to use + :param cores: The number of CPU cores to use + :param process_pool: An existing process pool to use + :param colnames: Column names to use for the resulting dataframe + :param na_value: Value to use for missing values in the dataframe + """ + if colnames and len(colnames) != len(models): + raise ValueError("Length of colnames must match length of models") + + pool = process_pool if process_pool else concurrent.futures.ProcessPoolExecutor(max_workers=cores) + shutdown = not process_pool # if the user provided a pool, do not shut it down + + func = partial(get_model_flux, objective=objective, solver=solver) + series: list[pd.Series] = list(pool.map(func, models)) + for i, series_obj in enumerate(series): + series_obj.name = colnames[i] if colnames else f"model_{i}" + df: pd.DataFrame = pd.concat(list(series), axis="columns") + + if shutdown: + pool.shutdown(wait=True) + + if na_value != NAType: # no need to replace values that are already pd.NA + df = df.fillna(na_value) + + df = df.T + return df + + +def group_reactions_by_pathway(models: cobra.Model | list[cobra.Model], flux_df: pd.DataFrame) -> pd.DataFrame: + pathways_by_reaction: dict[str, set[str]] = defaultdict(set) + models = [models] if isinstance(models, cobra.Model) else models + + for model in models: + for reaction in model.reactions: + reaction: cobra.Reaction + pathways_by_reaction[reaction.subsystem].add(reaction.id) + pathways_by_reaction.pop("", None) # remove the empty pathway; faster than checking every reaction's subsystem + + # pathway_flux: pd.DataFrame = pd.DataFrame(index=flux_df.index, columns=list(pathways_by_reaction.keys())) + # for condition in flux_df.index: + # for pathway, reactions in pathways_by_reaction.items(): + # pathway_flux.loc[condition, pathway] = flux_df.loc[condition, list(reactions)].sum() + pathway_fluxes: dict[str, pd.Series[npt.NDArray[np.floating]]] = {} + for pathway, reactions in pathways_by_reaction.items(): + reactions_in_df = list(reactions.intersection(flux_df.columns)) + if reactions_in_df: + pathway_fluxes[pathway] = flux_df[reactions_in_df].sum(axis=1) + return pd.DataFrame(pathway_fluxes) + + +def build_condition_vs_pathway_heatmap( + data: pd.DataFrame | list[cobra.Model] | Path | list[Path], + save_filepath: Path | None = None, + objective: str = "biomass_maintenance", + solver: str = "gurobi", + process_pool: concurrent.futures.ProcessPoolExecutor | None = None, + cores: int = 4, + condition_names: list[str] | None = None, + na_value: NAType | int | float = NAType, + *, + search_path: bool = False, + copy_df_when_building_plot: bool = False, + exclude_zero_flux_pathways: bool = False, +) -> plt.Figure: + """Create a heatmap of conditions vs flux through pathways. + + If `data` is a pd.DataFrame: + - The index names wile used as conditions and placed on the Y-axis + - The column names will be used as pathways and placed on the X-axis. The columns should indicate pathways. + + If `data` is a Path and `search_path` is True: + - Models will be recursively discovered under the given path + - Models will be simulated with the given objective and solver + - A dataframe will be built from the resulting series based on the above rules + + If `data` is a list of Paths: + - Models will be read and simulated for each path + - A pd.DataFrame will be built from the resulting series based on the above rules + + If `data` is a list of cobra.Models: + - Models will be simulated with the given objective and solver + - A pd.DataFrame will be built from the resulting series based on the above rules + + :param data: The data to use for the heatmap + :param search_path: Whether to search the given path for models + :param save_filepath: The filepath to save the heatmap to + :param objective: The objective function to optimize + :param solver: The solver to use + :param process_pool: An existing process pool to use + :param cores: The number of CPU cores to use + :param condition_names: Column names to use for the resulting dataframe if `data` is a Path or list of Paths + :param na_value: Value to use for missing values in the flux dataframe + :param copy_df_when_building_plot: Whether to copy the dataframe when building the plot. This can be useful if the dataframe is going to be reused later. + :param exclude_zero_flux_pathways: Whether to exclude pathways that have zero flux across all conditions + + + :return: A matplotlib Figure object containing the heatmap + """ + if not isinstance(data, Path) and search_path: + raise ValueError("If search_path is True, data must be a Path") + + flux_df: pd.DataFrame + if isinstance(data, pd.DataFrame): + return condition_vs_pathway( + data, + save_filepath=save_filepath, + copy_df=copy_df_when_building_plot, + exclude_zero_flux_pathways=exclude_zero_flux_pathways, + ) + elif isinstance(data, list) and isinstance(data[0], cobra.Model): + models = data + flux_df = get_many_model_flux( + models=data, + objective=objective, + solver=solver, + cores=cores, + process_pool=process_pool, + colnames=condition_names, + na_value=na_value, + ) + elif isinstance(data, Path): + if search_path: + possible_model_fps: list[Path] = find_possible_model_filepaths(data) + models = [] + for fp in possible_model_fps: + if isinstance(model := get_cobra_model_if_valid(fp), cobra.Model): + models.append(model) + flux_df = get_many_model_flux( + models, + objective=objective, + solver=solver, + cores=cores, + process_pool=process_pool, + colnames=condition_names, + na_value=na_value, + ) + else: + models = get_cobra_model_if_valid(data) + flux_df = pd.DataFrame(get_model_flux(models, objective=objective, solver=solver)) + elif isinstance(data, list) and isinstance(data[0], Path): + models = [get_cobra_model_if_valid(fp) for fp in data] + flux_df = get_many_model_flux( + models, + objective=objective, + solver=solver, + cores=cores, + process_pool=process_pool, + colnames=condition_names, + na_value=na_value, + ) + + flux_df = group_reactions_by_pathway(models=models, flux_df=flux_df) + return condition_vs_pathway(data=flux_df, save_filepath=save_filepath) + + +async def _main(): + models = [ + Path("/home/joshl/projects/ImmunoMetabolism/data/model_build/A/A_pDCs/A_pDCs_model_imat.json"), + Path("/home/joshl/projects/ImmunoMetabolism/data/model_build/B/B_pDCs/B_pDCs_model_imat.json"), + Path("/home/joshl/projects/ImmunoMetabolism/data/model_build/C/C_pDCs/C_pDCs_model_imat.json"), + Path("/home/joshl/projects/ImmunoMetabolism/data/model_build/D/D_pDCs/D_pDCs_model_imat.json"), + Path("/home/joshl/projects/ImmunoMetabolism/data/model_build/E/E_pDCs/E_pDCs_model_imat.json"), + ] + save_path = Path( + f"/home/joshl/projects/ImmunoMetabolism/results/figures/{models[0].stem.removeprefix('A_').removesuffix('_model_imat')}_heatmap.png" + ) + + fig = build_condition_vs_pathway_heatmap( + data=models, + cores=5, + condition_names=["Age Group A", "Age Group B", "Age Group C", "Age Group D", "Age Group E"], + save_filepath=save_path, + ) + fig.show() + + +if __name__ == "__main__": + import asyncio + + asyncio.run(_main()) From d65a219c4ceed92201861325e06b41e16d06c807 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 5 Sep 2025 11:31:34 -0500 Subject: [PATCH 231/265] chore: fix typo Signed-off-by: Josh Loecker --- tests/unit/test_data_types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/test_data_types.py b/tests/unit/test_data_types.py index 9688ddff..d5e1277a 100644 --- a/tests/unit/test_data_types.py +++ b/tests/unit/test_data_types.py @@ -2,7 +2,7 @@ def test_source_types(): - """Validate that source types always go in the order of 'trna', 'mrna', 'scrna', 'protemics'.""" + """Validate that source types always go in the order of 'trna', 'mrna', 'scrna', 'proteomics'.""" expected_order = ["trna", "mrna", "scrna", "proteomics"] for expected, source in zip(expected_order, SourceTypes): expected: str From 3e671d9de4ee0916accd810674e0a0c1ecfea889 Mon Sep 17 00:00:00 2001 From: JoshLoecker <47901540+JoshLoecker@users.noreply.github.com> Date: Fri, 5 Sep 2025 16:31:42 +0000 Subject: [PATCH 232/265] style: format code, Jupyter Notebook(s), and Python imports with `ruff` --- main/como/cluster_rnaseq.py | 12 +++-------- main/como/data_types.py | 10 ++-------- main/como/proteomics/Crux.py | 16 ++++----------- main/como/proteomics/FTPManager.py | 4 +--- main/como/proteomics/FileInformation.py | 4 +--- main/como/proteomics/proteomics_preprocess.py | 13 +++--------- main/como/proteomics_preprocessing.py | 20 +++++-------------- 7 files changed, 19 insertions(+), 60 deletions(-) diff --git a/main/como/cluster_rnaseq.py b/main/como/cluster_rnaseq.py index 2fb96cdc..1078b926 100644 --- a/main/como/cluster_rnaseq.py +++ b/main/como/cluster_rnaseq.py @@ -86,27 +86,21 @@ def __post_init__(self): # noqa: C901, ignore too complex level=LogLevel.ERROR, ) - if ( - isdigit(self.num_replicate_neighbors) and self.num_replicate_neighbors < 1 - ) or self.num_replicate_neighbors != "default": + if (isdigit(self.num_replicate_neighbors) and self.num_replicate_neighbors < 1) or self.num_replicate_neighbors != "default": _log_and_raise_error( "--n-neighbors-rep must be either 'default' or an integer > 1", error=ValueError, level=LogLevel.ERROR, ) - if ( - isdigit(self.num_batch_neighbors) and self.num_batch_neighbors < 1 - ) or self.num_batch_neighbors != "default": + if (isdigit(self.num_batch_neighbors) and self.num_batch_neighbors < 1) or self.num_batch_neighbors != "default": _log_and_raise_error( "--n-neighbors-batch must be either 'default' or an integer > 1", error=ValueError, level=LogLevel.ERROR, ) - if ( - isdigit(self.num_context_neighbors) and self.num_context_neighbors < 1 - ) or self.num_context_neighbors != "default": + if (isdigit(self.num_context_neighbors) and self.num_context_neighbors < 1) or self.num_context_neighbors != "default": _log_and_raise_error( "--n-neighbors-context must be either 'default' or an integer > 1", error=ValueError, diff --git a/main/como/data_types.py b/main/como/data_types.py index f9c11ca5..420471a6 100644 --- a/main/como/data_types.py +++ b/main/como/data_types.py @@ -11,11 +11,7 @@ from loguru import logger PATH_TYPE = str | Path -LOG_FORMAT = ( - "{time:YYYY-MM-DD HH:mm:ss} | " - "{level:<8} | " - "{name}:{line} - {message}" -) +LOG_FORMAT = "{time:YYYY-MM-DD HH:mm:ss} | {level:<8} | {name}:{line} - {message}" class AdjustmentMethod(Enum): @@ -139,9 +135,7 @@ class CobraCompartments: "s": ["eyespot", "eyespot apparatus", "stigma"], } - _REVERSE_LOOKUP: ClassVar[dict[str, list[str]]] = { - value.lower(): key for key, values in SHORTHAND.items() for value in values - } + _REVERSE_LOOKUP: ClassVar[dict[str, list[str]]] = {value.lower(): key for key, values in SHORTHAND.items() for value in values} @classmethod def get_shorthand(cls, longhand: str) -> str | None: diff --git a/main/como/proteomics/Crux.py b/main/como/proteomics/Crux.py index b9d0107f..9351cf4e 100644 --- a/main/como/proteomics/Crux.py +++ b/main/como/proteomics/Crux.py @@ -128,9 +128,7 @@ def mzml_to_sqt(self) -> None: ) # Replace all "comet.*" in output directory with the name of the file being processed - comet_files = [ - str(file) for file in os.listdir(file_information.sqt_base_path) if str(file).startswith("comet.") - ] + comet_files = [str(file) for file in os.listdir(file_information.sqt_base_path) if str(file).startswith("comet.")] for file_name in comet_files: # Determine the old file path old_file_path: Path = Path(file_information.sqt_base_path, file_name) @@ -242,9 +240,7 @@ def collect_uniprot_ids_and_ion_intensity(self) -> None: # Assign the file_information intensity dataframe to the gathered values self._file_information[i].intensity_df = pd.DataFrame(average_intensities_dict) - self._file_information[i].intensity_df = ( - self._file_information[i].intensity_df.groupby("uniprot", as_index=False).mean() - ) + self._file_information[i].intensity_df = self._file_information[i].intensity_df.groupby("uniprot", as_index=False).mean() async def _convert_uniprot_wrapper(self) -> None: """This function is a multiprocessing wrapper around the convert_ids function""" @@ -252,9 +248,7 @@ async def _convert_uniprot_wrapper(self) -> None: # Create a progress bar of results # From: https://stackoverflow.com/a/61041328/ - progress_bar = tqdm.tqdm( - desc="Starting UniProt to Gene Symbol conversion... ", total=len(self._file_information) - ) + progress_bar = tqdm.tqdm(desc="Starting UniProt to Gene Symbol conversion... ", total=len(self._file_information)) for i, result in enumerate(asyncio.as_completed(values)): await result # Get result from asyncio.as_completed progress_bar.set_description(f"Working on {i + 1} of {len(self._file_information)}") @@ -378,9 +372,7 @@ def split_abundance_values(self) -> None: # Create a new dataframe to split the S# columns from split_frame: pd.DataFrame = dataframe.copy() # Get the current S{i} columns in - abundance_columns: list[str] = [ - column for column in split_frame.columns if re.match(rf"{cell_type}_S{i}R\d+", column) - ] + abundance_columns: list[str] = [column for column in split_frame.columns if re.match(rf"{cell_type}_S{i}R\d+", column)] take_columns: list[str] = ["symbol"] + abundance_columns average_intensity_name: str = f"{cell_type}_S{i}" diff --git a/main/como/proteomics/FTPManager.py b/main/como/proteomics/FTPManager.py index d2807cc8..b3b96052 100644 --- a/main/como/proteomics/FTPManager.py +++ b/main/como/proteomics/FTPManager.py @@ -21,9 +21,7 @@ from como.data_types import LogLevel -async def aioftp_client( - host: str, username: str = "anonymous", password: str = "guest", port: int = 21, max_attempts: int = 3 -) -> aioftp.Client: +async def aioftp_client(host: str, username: str = "anonymous", password: str = "guest", port: int = 21, max_attempts: int = 3) -> aioftp.Client: """This class is responsible for creating a "client" connection""" connection_successful: bool = False attempt_num: int = 1 diff --git a/main/como/proteomics/FileInformation.py b/main/como/proteomics/FileInformation.py index 0b37a4b6..59a4a2ee 100644 --- a/main/como/proteomics/FileInformation.py +++ b/main/como/proteomics/FileInformation.py @@ -68,9 +68,7 @@ def __init__( self.sqt_base_path: Path = sqt_path.parent if intensity_csv is None: - self.intensity_csv: Path = Path( - project.configs.data_dir, "data_matrices", cell_type, f"protein_abundance_matrix_{cell_type}.csv" - ) + self.intensity_csv: Path = Path(project.configs.data_dir, "data_matrices", cell_type, f"protein_abundance_matrix_{cell_type}.csv") else: self.intensity_csv: Path = intensity_csv diff --git a/main/como/proteomics/proteomics_preprocess.py b/main/como/proteomics/proteomics_preprocess.py index 7a7df11d..86be1523 100644 --- a/main/como/proteomics/proteomics_preprocess.py +++ b/main/como/proteomics/proteomics_preprocess.py @@ -160,9 +160,7 @@ def _gather_data(self): # Iterate through the URLs available for url, study in zip(ftp_urls, studies): - ftp_data: FTPManager.Reader = FTPManager.Reader( - root_link=url, file_extensions=self._preferred_extensions - ) + ftp_data: FTPManager.Reader = FTPManager.Reader(root_link=url, file_extensions=self._preferred_extensions) urls = list(ftp_data.files) sizes = list(ftp_data.file_sizes) @@ -170,9 +168,7 @@ def _gather_data(self): # Iterate through all files and sizes found for url_## for file, size in zip(urls, sizes): - self.file_information.append( - FileInformation(cell_type=cell_type, download_url=file, file_size=size, study=study) - ) + self.file_information.append(FileInformation(cell_type=cell_type, download_url=file, file_size=size, study=study)) def print_download_size(self): """Print the total size to download if we must download data.""" @@ -323,10 +319,7 @@ def parse_args() -> argparse.Namespace: else: args.core_count = int(args.core_count) if args.core_count > os.cpu_count(): - logger.info( - f"{args.core_count} cores not available, system only has {os.cpu_count()} cores. " - f"Setting '--cores' to {os.cpu_count()}" - ) + logger.info(f"{args.core_count} cores not available, system only has {os.cpu_count()} cores. Setting '--cores' to {os.cpu_count()}") args.core_count = os.cpu_count() return args diff --git a/main/como/proteomics_preprocessing.py b/main/como/proteomics_preprocessing.py index 1329406d..21f38a78 100644 --- a/main/como/proteomics_preprocessing.py +++ b/main/como/proteomics_preprocessing.py @@ -36,15 +36,9 @@ def z_score_calc(abundance: pd.DataFrame, min_thresh: int) -> ZResult: # np.zeros((1000, len(abundance.columns)), dtype=np.float64), z_result = ZResult( - zfpkm=pd.DataFrame( - data=np.nan * np.ones_like(values), index=abundance.index, columns=abundance.columns, dtype=np.float64 - ), - x_range=pd.DataFrame( - data=np.zeros((1000, len(abundance.columns))), columns=abundance.columns, dtype=np.float64 - ), - density=pd.DataFrame( - data=np.zeros((1000, len(abundance.columns))), columns=abundance.columns, dtype=np.float64 - ), + zfpkm=pd.DataFrame(data=np.nan * np.ones_like(values), index=abundance.index, columns=abundance.columns, dtype=np.float64), + x_range=pd.DataFrame(data=np.zeros((1000, len(abundance.columns))), columns=abundance.columns, dtype=np.float64), + density=pd.DataFrame(data=np.zeros((1000, len(abundance.columns))), columns=abundance.columns, dtype=np.float64), mu=np.zeros(len(abundance.columns)), std_dev=np.zeros(len(abundance.columns)), max_fpkm_peak=np.zeros(len(abundance.columns)), @@ -98,9 +92,7 @@ def plot_gaussian_fit(z_results: ZResult, facet_titles: bool = True, x_min: int std_dev = z_results.std_dev max_fpkm = z_results.max_fpkm_peak - fig = make_subplots( - rows=len(zfpkm.columns), cols=1, subplot_titles=zfpkm.columns if facet_titles else [None] * len(zfpkm.columns) - ) + fig = make_subplots(rows=len(zfpkm.columns), cols=1, subplot_titles=zfpkm.columns if facet_titles else [None] * len(zfpkm.columns)) for i, col in enumerate(zfpkm.columns): fitted = stats.norm.pdf(x_range[col], loc=mu[i], scale=std_dev[i]) scale_fit = fitted * (max_fpkm[i] / fitted.max()) @@ -136,9 +128,7 @@ def protein_transform_main( output_z_score_matrix_filepath: Path, ) -> None: """Transform protein abundance data.""" - abundance_df: pd.DataFrame = ( - pd.read_csv(abundance_df) if isinstance(abundance_df, (str, Path)) else abundance_df.fillna(0) - ) + abundance_df: pd.DataFrame = pd.read_csv(abundance_df) if isinstance(abundance_df, (str, Path)) else abundance_df.fillna(0) abundance_df = abundance_df[np.isfinite(abundance_df).all(axis=1)] # Remove +/- infinity values z_transform: ZResult = z_score_calc(abundance_df, min_thresh=0) From 1e0a5bb23d914f1a7acb56dbd948f000428a67fa Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 5 Sep 2025 11:34:35 -0500 Subject: [PATCH 233/265] fix: break up complex conditional Signed-off-by: Josh Loecker --- main/como/rnaseq_gen.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index d4ba7335..6df3221f 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -532,7 +532,11 @@ def cpm_filter( top_samples = round(n_top * len(counts.columns)) # noqa: F841 test_bools = pd.DataFrame({"entrez_gene_ids": entrez_ids}) for i in range(len(counts_per_million.columns)): - cutoff = 10e6 / (np.median(np.sum(counts[:, i]))) if cut_off == "default" else (1e6 * cut_off) / np.median(np.sum(counts[:, i])) + median_sum = np.float64(np.median(np.sum(counts[:, i]))) + if cut_off == "default": # noqa: SIM108 + cutoff = np.float64(10e6) / median_sum + else: + cutoff = np.float64(1e6 * cut_off) / median_sum test_bools = test_bools.merge(counts_per_million[counts_per_million.iloc[:, i] > cutoff]) return metrics From 6adaa7b1880e76a3d0f37c2afb632886f9b523f6 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 5 Sep 2025 11:36:10 -0500 Subject: [PATCH 234/265] fix: _validate_source_arguments requires arg expansion Signed-off-by: Josh Loecker --- main/como/merge_xomics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index b613b92a..61153270 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -575,7 +575,7 @@ async def merge_xomics( # noqa: C901 } # fmt: on for source in source_data: - _validate_source_arguments(source, source_data[source]) + _validate_source_arguments(source, *source_data[source]) if all( file is None From c26f437321bf1c6691529075f3de0ff27b748b87 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 5 Sep 2025 11:36:27 -0500 Subject: [PATCH 235/265] fix: typo Signed-off-by: Josh Loecker --- main/como/merge_xomics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index 61153270..fe46fc98 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -128,7 +128,7 @@ def _merge_logical_table(df: pd.DataFrame): df = pd.concat([df, pd.DataFrame(duplicate_rows)], axis=0, ignore_index=True) df.drop(df[df["entrez_gene_id"] == i].index, inplace=True) - logger.trace(f"Shape after merging duplciated rows: {df.shape}") + logger.trace(f"Shape after merging duplicated rows: {df.shape}") full_entrez_id_sets: set[str] = set() entrez_dups_list: list[list[str]] = [] From da2beaf62bf0c823bd5d197aa3f3f12ada9a3563 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 5 Sep 2025 11:36:49 -0500 Subject: [PATCH 236/265] fix: typo Signed-off-by: Josh Loecker --- main/como/data_types.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/main/como/data_types.py b/main/como/data_types.py index f9c11ca5..43e00f4c 100644 --- a/main/como/data_types.py +++ b/main/como/data_types.py @@ -11,11 +11,7 @@ from loguru import logger PATH_TYPE = str | Path -LOG_FORMAT = ( - "{time:YYYY-MM-DD HH:mm:ss} | " - "{level:<8} | " - "{name}:{line} - {message}" -) +LOG_FORMAT = "{time:YYYY-MM-DD HH:mm:ss} | {level:<8} | {name}:{line} - {message}" class AdjustmentMethod(Enum): @@ -139,9 +135,7 @@ class CobraCompartments: "s": ["eyespot", "eyespot apparatus", "stigma"], } - _REVERSE_LOOKUP: ClassVar[dict[str, list[str]]] = { - value.lower(): key for key, values in SHORTHAND.items() for value in values - } + _REVERSE_LOOKUP: ClassVar[dict[str, list[str]]] = {value.lower(): key for key, values in SHORTHAND.items() for value in values} @classmethod def get_shorthand(cls, longhand: str) -> str | None: @@ -215,7 +209,7 @@ def __setitem__(self, key, value): def _validate_attribute(self, key): if key not in {i.value for i in SourceTypes._member_map_.values()}: - # Unable to use como.utils._log_and_raise_error becuase it results in a circular import + # Unable to use como.utils._log_and_raise_error because it results in a circular import message = f"{key} is not a valid attribute of {SourceTypes.__name__}; got '{key}'" logger.warning(message) raise ValueError(message) From 462ef3ff96f139c1a5948cdd59e5162282dce3d9 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 5 Sep 2025 13:17:33 -0500 Subject: [PATCH 237/265] refactor: simplify function signatures and improve docstrings Updated several functions to use clearer argument names and added detailed docstrings following the Google style guide. Removed unnecessary async/await patterns where not needed, enhancing readability and maintainability. Signed-off-by: Josh Loecker --- main/COMO.ipynb | 7 + main/como/combine_distributions.py | 39 ++++- main/como/create_context_specific_model.py | 89 +++++++++- main/como/data_types.py | 25 ++- main/como/merge_xomics.py | 39 +++-- main/como/migrations.py | 9 +- .../pipelines/build_condition_heatmaps.py | 131 +++++++-------- main/como/plot/heatmap.py | 14 +- main/como/project.py | 47 +++++- main/como/proteomics/proteomics_preprocess.py | 19 ++- main/como/proteomics_gen.py | 33 +++- main/como/proteomics_preprocessing.py | 34 +++- main/como/rnaseq_gen.py | 154 +++++++++++++++--- main/como/rnaseq_preprocess.py | 29 +++- main/como/utils.py | 62 ++++--- ruff.toml | 4 + tests/unit/test_data_types.py | 2 +- tests/unit/test_rnaseq_preprocess.py | 2 +- 18 files changed, 566 insertions(+), 173 deletions(-) diff --git a/main/COMO.ipynb b/main/COMO.ipynb index 344dc8ae..df6df0b3 100644 --- a/main/COMO.ipynb +++ b/main/COMO.ipynb @@ -238,6 +238,13 @@ " \"\"\"Get the directory of the COMO.ipynb notebook.\n", "\n", " This is used to set the proper input and output paths for the rest of the notebook\n", + "\n", + "\n", + " Returns:\n", + " The directory containing the `COMO.ipynb` notebook\n", + "\n", + " Raises:\n", + " FileNotFoundError: If the root directory could not be determined\n", " \"\"\"\n", " current_dir = Path().cwd()\n", "\n", diff --git a/main/como/combine_distributions.py b/main/como/combine_distributions.py index 5311fd9b..7549d1f6 100644 --- a/main/como/combine_distributions.py +++ b/main/como/combine_distributions.py @@ -23,7 +23,7 @@ ) -async def _combine_z_distribution_for_batch( +def _combine_z_distribution_for_batch( context_name: str, batch: _BatchEntry, matrix: pd.DataFrame, @@ -33,6 +33,21 @@ async def _combine_z_distribution_for_batch( weighted_z_floor: int, weighted_z_ceiling: int, ) -> pd.DataFrame: + """Combine z-score distributions across samples for a single batch. + + Args: + context_name: Name of the context (e.g., tissue or condition). + batch: Batch entry containing batch number and sample names. + matrix: DataFrame with 'ensembl_gene_id' and sample columns. + source: Source type (e.g., trna, mrna, scrna, proteomics). + output_combined_matrix_filepath: Path to save the combined z-score matrix. + output_figure_dirpath: Path to save the z-score distribution figure. + weighted_z_floor: Minimum z-score value after combining. + weighted_z_ceiling: Maximum z-score value after combining. + + Returns: + A pandas dataframe of the weighted z-distributions + """ output_combined_matrix_filepath.parent.mkdir(parents=True, exist_ok=True) output_figure_dirpath.mkdir(parents=True, exist_ok=True) @@ -80,7 +95,7 @@ async def _combine_z_distribution_for_batch( return weighted_matrix -async def _combine_z_distribution_for_source( +def _combine_z_distribution_for_source( merged_source_data: pd.DataFrame, context_name: str, num_replicates: int, @@ -88,7 +103,21 @@ async def _combine_z_distribution_for_source( output_figure_filepath: Path, weighted_z_floor: int = -6, weighted_z_ceiling: int = 6, -): +) -> pd.DataFrame: + """Combine z-score distributions across batches for a single source. + + Args: + merged_source_data: DataFrame with 'ensembl_gene_id' and batch columns. + context_name: Name of the context (e.g., tissue or condition). + num_replicates: Number of replicates (samples) for weighting. + output_combined_matrix_filepath: Path to save the combined z-score matrix. + output_figure_filepath: Path to save the z-score distribution figure. + weighted_z_floor: Minimum z-score value after combining. + weighted_z_ceiling: Maximum z-score value after combining. + + Returns: + A pandas dataframe of the weighted z-distributions + """ if _num_columns(merged_source_data) <= 2: logger.warning("A single source exists, returning matrix as-is because no additional combining can be done") merged_source_data.columns = ["ensembl_gene_id", "combine_z"] @@ -144,7 +173,7 @@ def _combine_z_distribution_for_context( return pd.DataFrame({"ensembl_gene_id": [], "combine_z": []}) z_matrices = [ - res.z_score_matrix.set_index("ensembl_gene_id").rename(columns={col: res.type.value for col in res.z_score_matrix.columns[1:]}) + res.z_score_matrix.set_index("ensembl_gene_id").rename(columns=dict.fromkeys(res.z_score_matrix.columns[1:], res.type.value)) for res in zscore_results ] z_matrix = pd.concat(z_matrices, axis=1, join="outer").reset_index() @@ -239,7 +268,7 @@ async def _begin_combining_distributions( for df in batch_results: merged_batch_results = df if merged_batch_results.empty else merged_batch_results.merge(df, on="ensembl_gene_id", how="outer") - merged_source_results: pd.DataFrame = await _combine_z_distribution_for_source( + merged_source_results: pd.DataFrame = _combine_z_distribution_for_source( merged_source_data=merged_batch_results, context_name=context_name, num_replicates=sum(batch.num_samples for batch in batch_names[source.value]), diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 6ac2327e..0a50890b 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -25,7 +25,15 @@ def _correct_bracket(rule: str, name: str) -> str: - """Correct GPR rules to format readable by.""" + """Correct GPR rules to format readable by. + + Args: + rule: GPR rule string from a COBRA model + name: Gene name string from a COBRA model + + Returns: + A corrected GPR rule string + """ rule_match = re.search(r"or|and", rule) name_match = re.search(r"or|and", name) if rule_match is None or name_match is None: @@ -54,7 +62,15 @@ def _correct_bracket(rule: str, name: str) -> str: def _gene_rule_logical(gpr_expression: str, level: int = 0) -> str: - """Create an expression from GPR rule which can be evaluated as true or false.""" + """Create an expression from GPR rule which can be evaluated as true or false. + + Args: + gpr_expression: GPR rule string from a COBRA model + level: Current recursion level (used for debugging) + + Returns: + An evaluable string where "and" is replaced with "min" and "or" is replaced with "max" + """ try: loc_r = gpr_expression.index(")") except ValueError: @@ -95,9 +111,9 @@ def _set_boundaries( upper_bounds: list[float], ) -> cobra.Model: # get boundary reactions - exchange_rxns = [rxn.id for rxn in model.reactions if re.search("EX_", rxn.id)] - sink_rxns = [rxn.id for rxn in model.reactions if re.search("sink_", rxn.id)] - demand_rxns = [rxn.id for rxn in model.reactions if re.search("DM_", rxn.id)] + exchange_rxns = [rxn.id for rxn in model.reactions if "EX_" in rxn.id] + sink_rxns = [rxn.id for rxn in model.reactions if "sink_" in rxn.id] + demand_rxns = [rxn.id for rxn in model.reactions if "DM_" in rxn.id] # Allows all boundary reactions to be used if none are given allow_all_boundary_rxns = not boundary_reactions @@ -181,7 +197,7 @@ def _build_with_fastcore(cobra_model, s_matrix, lower_bounds, upper_bounds, exp_ # e1003424.' logger.warning("Fastcore requires a flux consistant model is used as refererence, to achieve this fastcc is required which is NOT reproducible.") logger.debug("Creating feasible model") - incon_rxns, cobra_model = _feasibility_test(cobra_model, "other") + _, cobra_model = _feasibility_test(cobra_model, "other") properties = FastcoreProperties(core=exp_idx_list, solver=solver) algorithm = FASTcore(s_matrix, lower_bounds, upper_bounds, properties) context_rxns = algorithm.fastcore() @@ -263,6 +279,19 @@ async def _map_expression_to_reaction( """Map gene ids to a reaction based on GPR (gene to protein to reaction) association rules. These rules should be defined in the general genome-scale metabolic model + + Args: + reference_model: A COBRA model object representing the general genome-scale metabolic model. + gene_expression_file: Path to a gene expression file (.csv, .tsv, .xlsx, or .xls) + recon_algorithm: Algorithm to use for reconstruction (GIMME, FASTCORE, iMAT, or tINIT) + low_thresh: Low expression threshold for algorithms that require it (iMAT, tINIT) + high_thresh: High expression threshold for algorithms that require it (iMAT, tINIT) + + Returns: + An ordered dictionary mapping reaction IDs to their corresponding expression values. + + Raises: + ValueError: If neither 'entrez_gene_id' nor 'ensembl_gene_id' columns are found in the gene expression file. """ expression_data = await _read_file(gene_expression_file) identifier_column = next((col for col in ("entrez_gene_id", "ensembl_gene_id") if col in expression_data.columns), "") @@ -282,8 +311,8 @@ async def _map_expression_to_reaction( # Define a default expression value if a gene ID is not found default_expression = ( np.mean([low_thresh, high_thresh]) if recon_algorithm in {Algorithm.IMAT, Algorithm.TINIT} - else -1 if recon_algorithm in {Algorithm.GIMME} - else 0 if recon_algorithm in {Algorithm.FASTCORE} + else -1 if recon_algorithm == Algorithm.GIMME + else 0 if recon_algorithm == Algorithm.FASTCORE else 1 ) # fmt: on @@ -339,6 +368,24 @@ async def _build_model( # noqa: C901 Core reactions that do not necessarily meet GPR association requirements can be forced if in the force reaction file. Metabolite exchange (media), sinks, and demands are determined from exchanges file. Reactions can also be force excluded even if they meet GPR association requirements using the force exclude file. + + Args: + general_model_file: Path to a COBRA model file (.xml, .mat, or .json) + gene_expression_file: Path to a gene expression file (.csv, .tsv, .xlsx, or .xls) + recon_algorithm: Algorithm to use for reconstruction (GIMME, FASTCORE, iMAT, or tINIT) + objective: Objective reaction ID in the general model + boundary_reactions: List of boundary reactions to set in the model + exclude_reactions: List of reactions to exclude from the model + force_reactions: List of reactions to force include in the model + lower_bounds: List of lower bounds corresponding to boundary reactions + upper_bounds: List of upper bounds corresponding to boundary reactions + solver: Solver to use (e.g., 'glpk', 'cplex', 'gurobi') + low_thresh: Low expression threshold for algorithms that require it (iMAT, tINIT) + high_thresh: High expression threshold for algorithms that require it (iMAT, tINIT) + output_flux_result_filepath: Path to save flux results (for iMAT only) + + Returns: + A _BuildResults object containing the context-specific model, list of expression indices used, and a DataFrame of infeasible reactions. """ reference_model: cobra.Model match general_model_file.suffix: @@ -583,7 +630,31 @@ async def create_context_specific_model( # noqa: C901 log_level: LogLevel = LogLevel.INFO, log_location: str | TextIOWrapper = sys.stderr, ): - """Create a context-specific model using the provided data.""" + """Create a context-specific model using the provided data. + + Args: + context_name: Name of the context-specific model. + reference_model: Path to the general genome-scale metabolic model file (.xml, .mat, or .json). + active_genes_filepath: Path to the gene expression data file (csv, tsv, or Excel). + output_infeasible_reactions_filepath: Path to save infeasible reactions (csv). + output_flux_result_filepath: Path to save flux results (csv). + output_model_filepaths: Path or list of paths to save the context-specific model (.xml, .mat, or .json). + output_filetypes: List of file types to save the model as ('xml', 'mat', 'json'). + output_fastcore_expression_index_filepath: Path to save Fastcore expression indices (txt). Required if using Fastcore. + objective: Objective function reaction ID. + boundary_rxns_filepath: Optional path to boundary reactions file (csv, tsv, or Excel). + exclude_rxns_filepath: Optional path to reactions to exclude file (csv, tsv, or Excel). + force_rxns_filepath: Optional path to reactions to force include file (csv, tsv, or Excel). + algorithm: Algorithm to use for reconstruction. One of Algorithm.GIMME, Algorithm.FASTCORE, Algorithm.IMAT, Algorithm.TINIT. + low_threshold: Low expression threshold for algorithms that require it. + high_threshold: High expression threshold for algorithms that require it. + solver: Solver to use. One of Solver.GLPK, Solver.CPLEX, Solver.GUROBI + log_level: Logging level. One of LogLevel.DEBUG, LogLevel.INFO, LogLevel.WARNING, LogLevel.ERROR, LogLevel.CRITICAL + log_location: Location for log output. Can be a file path or sys.stderr/sys.stdout. + + Raises: + ImportError: If Gurobi solver is selected but gurobipy is not installed. + """ _set_up_logging(level=log_level, location=log_location) output_model_filepaths = [output_model_filepaths] if isinstance(output_model_filepaths, Path) else output_model_filepaths for path in output_model_filepaths: diff --git a/main/como/data_types.py b/main/como/data_types.py index 43e00f4c..177edf6f 100644 --- a/main/como/data_types.py +++ b/main/como/data_types.py @@ -139,12 +139,26 @@ class CobraCompartments: @classmethod def get_shorthand(cls, longhand: str) -> str | None: - """Get the short-hand compartment name from the long-hand name.""" + """Get the short-hand compartment name from the long-hand name. + + Args: + longhand: The long-hand compartment name (e.g., 'cytoplasm', 'extracellular'). + + Returns: + The short-hand compartment name if found, None otherwise. + """ return cls._REVERSE_LOOKUP.get(longhand.lower(), None) @classmethod def get_longhand(cls, shorthand: str) -> str | None: - """Get the long-hand compartment name from the short-hand name.""" + """Get the long-hand compartment name from the short-hand name. + + Args: + shorthand: The short-hand compartment name (e.g., 'c', 'e', 'm'). + + Returns: + The long-hand compartment name if found, None otherwise. + """ longhand = cls.SHORTHAND.get(shorthand.lower(), None) return longhand[0] if longhand else None @@ -192,8 +206,11 @@ class _BaseDataType: def __getitem__(self, value: str): """Access matrices using square bracket notation (e.g., `input_matrices['total_rna']`). - :param value: The name of the matrix to get ('trna', 'mrna', 'scrna', 'proteomics') - :returns: The DataFrame if it exists, None otherwise. + Args: + value: The name of the matrix to get ('trna', 'mrna', 'scrna', 'proteomics') + + Returns: + The DataFrame if it exists, None otherwise. """ self._validate_attribute(value) return getattr(self, value) diff --git a/main/como/merge_xomics.py b/main/como/merge_xomics.py index fe46fc98..a8b81652 100644 --- a/main/como/merge_xomics.py +++ b/main/como/merge_xomics.py @@ -50,8 +50,17 @@ class _HighExpressionHeaderNames: # TODO: If function is no longer needed, remove? -async def _load_rnaseq_tests(filename, context_name, prep_method: RNAType) -> tuple[str, pd.DataFrame]: - """Load rnaseq results.""" +def _load_rnaseq_tests(filename, context_name, prep_method: RNAType) -> tuple[str, pd.DataFrame]: + """Load rnaseq results. + + Args: + filename: Name of the file to load + context_name: Name of the context (e.g., tissue or cell type) + prep_method: The RNA-seq library preparation method (e.g., mRNA, total RNA, single-cell RNA) + + Returns: + A tuple containing the context name and the loaded DataFrame± + """ logger.debug(f"Loading data for context '{context_name}' using preparation method '{prep_method.value}'") config = Config() @@ -103,8 +112,11 @@ def load_dummy_dict(): def _merge_logical_table(df: pd.DataFrame): """Merge rows of Logical Table belonging to the same entrez_gene_id. - :param df: pandas dataframe of logical table - :return: pandas dataframe of merged table + Args: + df: Pandas dataframe containing the logical table + + Returns: + pandas dataframe of merged table """ # step 1: get all plural ENTREZ_GENE_IDs in the input table, extract unique IDs df.dropna(subset=["entrez_gene_id"], inplace=True) @@ -135,6 +147,7 @@ def _merge_logical_table(df: pd.DataFrame): multi_entrez_index = list(range(len(multiple_entrez_ids))) logger.trace("Starting to merge multiple entrez IDs") + temp_multi_entrez_index = multi_entrez_index.copy() for i in range(len(multiple_entrez_ids)): if i not in multi_entrez_index: continue @@ -142,23 +155,25 @@ def _merge_logical_table(df: pd.DataFrame): logger.trace(f"Iterating through multi-entrez ids, index {i}") set1 = set(multiple_entrez_ids[i].split("//")) - multi_entrez_index.remove(i) + temp_multi_entrez_index.remove(i) for j in multi_entrez_index: set2 = set(multiple_entrez_ids[j].split("//")) intersect = set1.intersection(set2) if bool(intersect): set1 = set1.union(set2) - multi_entrez_index.remove(j) + temp_multi_entrez_index.remove(j) sortlist = list(set1) sortlist.sort(key=int) new_entrez_id = " /// ".join(sortlist) full_entrez_id_sets.add(new_entrez_id) + multi_entrez_index = temp_multi_entrez_index.copy() + logger.debug(f"Finished merging multiple entrez IDs, found {len(full_entrez_id_sets)} sets") entrez_dups_list.extend(i.split(" /// ") for i in full_entrez_id_sets) - entrez_dups_dict = dict(zip(full_entrez_id_sets, entrez_dups_list)) + entrez_dups_dict = dict(zip(full_entrez_id_sets, entrez_dups_list, strict=True)) logger.trace("Replacing IDs in dataframe") for merged_entrez_id, entrez_dups_list in entrez_dups_dict.items(): @@ -193,8 +208,12 @@ async def _get_transcriptmoic_details(merged_df: pd.DataFrame, taxon_id: int) -> The resulting dataframe will have its columns created in the order listed above It will return a pandas dataframe with this information - :param merged_df: A dataframe containing all active transcriptomic and proteomic genes - :return: A dataframe with the above-listed columns + Args: + merged_df: A dataframe containing all active transcriptomic and proteomic genes + taxon_id: The NCBI taxonomy ID of the organism + + Returns: + A dataframe with the above-listed columns """ # If _ExpressedHeaderNames.PROTEOMICS.value is in the dataframe, lower the required expression by 1 # We are only trying to get details for transcriptomic data @@ -486,7 +505,7 @@ def _build_batches( proteomic_metadata: pd.DataFrame | None, ) -> _BatchNames: batch_names = _BatchNames(**{source.name.lower(): [] for source in SourceTypes}) - for source, metadata in zip(SourceTypes, [trna_metadata, mrna_metadata, scrna_metadata, proteomic_metadata]): + for source, metadata in zip(SourceTypes, [trna_metadata, mrna_metadata, scrna_metadata, proteomic_metadata], strict=True): source: SourceTypes metadata: pd.DataFrame if metadata is None: diff --git a/main/como/migrations.py b/main/como/migrations.py index 61ac6abf..c1d291b1 100644 --- a/main/como/migrations.py +++ b/main/como/migrations.py @@ -2,5 +2,12 @@ def gene_info_migrations(df: pd.DataFrame) -> pd.DataFrame: - """Migrate gene info DataFrame to the latest version.""" + """Migrate gene info DataFrame to the latest version. + + Args: + df: The input DataFrame containing gene information. + + Returns: + The migrated DataFrame with updated column names. + """ return df.rename(columns={"hgnc_symbol": "gene_symbol"}) if "hgnc_symbol" in df.columns else df diff --git a/main/como/pipelines/build_condition_heatmaps.py b/main/como/pipelines/build_condition_heatmaps.py index a0161a45..16b970b8 100644 --- a/main/como/pipelines/build_condition_heatmaps.py +++ b/main/como/pipelines/build_condition_heatmaps.py @@ -10,65 +10,36 @@ from functools import partial from pathlib import Path -import aiofiles.os -import aiofiles.ospath import cobra import matplotlib.pyplot as plt import numpy as np import numpy.typing as npt -import orjson import pandas as pd from pandas._libs.missing import NAType from como.plot.heatmap import condition_vs_pathway -async def afind_possible_model_filepaths(search_dir: Path) -> list[Path]: - """Asynchronously find potential files that could be constraint-based metabolic models. - - :param search_dir: The directory to search for models. - :return: Potential filepaths that could be loaded as a `cobra.Model` object - """ - return [f for f in list(await asyncio.to_thread(search_dir.rglob, pattern="*")) if f.suffix in {".mat", ".json", ".sbml", ".xml"}] - - def find_possible_model_filepaths(search_dir: Path) -> list[Path]: """Find potential files that could be constraint-based metabolic models. - :param search_dir: The directory to search for models. - :return: Potential filepaths that could be loaded as a `cobra.Model` object - """ - return [f for f in search_dir.rglob("*") if f.suffix in {".mat", ".json", ".sbml", ".xml"}] - - -async def ais_filepath_a_model(filepath: Path) -> cobra.Model | None: - """Asynchronously evaluate if a given filepath can be read as a `cobra.Model`. + Args: + search_dir: The directory to search for models. - :param filepath: The filepath to read - :return a `cobra.Model` object if the file can be read, otherwise None + Returns: + Potential filepaths that could be loaded as a `cobra.Model` object """ - suffix = filepath.suffix.lower() - if suffix == ".mat": - return await asyncio.to_thread(cobra.io.load_matlab_model, infile_path=filepath) - elif suffix in {".xml", ".sbml"}: - return await asyncio.to_thread(cobra.io.read_sbml_model, filename=filepath) - elif suffix in {".yaml", ".yml"}: - async with aiofiles.open(filepath) as i_stream: - content = await i_stream.read() - return cobra.io.from_yaml(content) - elif suffix == ".json": - async with aiofiles.open(filepath) as i_stream: - content = await i_stream.read() - data = orjson.loads(content) - return cobra.io.model_from_dict(data) - return None + return [f for f in search_dir.rglob("*") if f.suffix in {".mat", ".json", ".sbml", ".xml"}] def get_cobra_model_if_valid(filepath: Path) -> cobra.Model | None: """Evaluate if a given filepath can be read as a `cobra.Model`. - :param filepath: The filepath to read - :return a `cobra.Model` object if the file can be read, otherwise None + Args: + filepath: The filepath to read + + Returns: + a `cobra.Model` object if the file can be read, otherwise None """ if filepath.suffix == ".json": return cobra.io.load_json_model(filepath) @@ -84,10 +55,13 @@ def get_cobra_model_if_valid(filepath: Path) -> cobra.Model | None: def get_model_flux(model: cobra.Model, objective: str = "biomass_maintenance", solver: str = "gurobi") -> pd.Series: """Get the flux through a CBMM. - :param model: A `cobra.Model` object - :param objective: The objective function to optimize - :param solver: The solver to use - :return: A pandas Series of reaction fluxes indexed by reaction ID + Args: + model: A `cobra.Model` object + objective: The objective function to optimize + solver: The solver to use + + Returns: + A pandas Series of reaction fluxes indexed by reaction ID """ model.objective = objective model.solver = solver @@ -106,18 +80,25 @@ def get_many_model_flux( ) -> pd.DataFrame: """Get the flux through many CBMMs. - :param models: A list of `cobra.Model` objects - :param objective: The objective function to optimize - :param solver: The solver to use - :param cores: The number of CPU cores to use - :param process_pool: An existing process pool to use - :param colnames: Column names to use for the resulting dataframe - :param na_value: Value to use for missing values in the dataframe + Args: + models: A list of `cobra.Model` objects + objective: The objective function to optimize + solver: The solver to use + cores: The number of CPU cores to use + process_pool: An existing process pool to use + colnames: Column names to use for the resulting dataframe + na_value: Value to use for missing values in the dataframe + + Returns: + A pandas DataFrame of reaction fluxes indexed by condition (row) and reaction ID (column) + + Raises: + ValueError: If `colnames` is provided and its length does not match the number of models """ if colnames and len(colnames) != len(models): raise ValueError("Length of colnames must match length of models") - pool = process_pool if process_pool else concurrent.futures.ProcessPoolExecutor(max_workers=cores) + pool = process_pool or concurrent.futures.ProcessPoolExecutor(max_workers=cores) shutdown = not process_pool # if the user provided a pool, do not shut it down func = partial(get_model_flux, objective=objective, solver=solver) @@ -137,6 +118,15 @@ def get_many_model_flux( def group_reactions_by_pathway(models: cobra.Model | list[cobra.Model], flux_df: pd.DataFrame) -> pd.DataFrame: + """Group reactions by their subsystem/pathway and sum the fluxes. + + Args: + models: A cobra.Model or list of cobra.Models + flux_df: A dataframe of reaction fluxes, indexed by condition and with reaction IDs as columns + + Returns: + A dataframe of pathway fluxes, indexed by condition and with pathways as columns + """ pathways_by_reaction: dict[str, set[str]] = defaultdict(set) models = [models] if isinstance(models, cobra.Model) else models @@ -191,20 +181,25 @@ def build_condition_vs_pathway_heatmap( - Models will be simulated with the given objective and solver - A pd.DataFrame will be built from the resulting series based on the above rules - :param data: The data to use for the heatmap - :param search_path: Whether to search the given path for models - :param save_filepath: The filepath to save the heatmap to - :param objective: The objective function to optimize - :param solver: The solver to use - :param process_pool: An existing process pool to use - :param cores: The number of CPU cores to use - :param condition_names: Column names to use for the resulting dataframe if `data` is a Path or list of Paths - :param na_value: Value to use for missing values in the flux dataframe - :param copy_df_when_building_plot: Whether to copy the dataframe when building the plot. This can be useful if the dataframe is going to be reused later. - :param exclude_zero_flux_pathways: Whether to exclude pathways that have zero flux across all conditions - - - :return: A matplotlib Figure object containing the heatmap + Args: + data: The data to use for the heatmap + search_path: Whether to search the given path for models + save_filepath: The filepath to save the heatmap to + objective: The objective function to optimize + solver: The solver to use + process_pool: An existing process pool to use + cores: The number of CPU cores to use + condition_names: Column names to use for the resulting dataframe if `data` is a Path or list of Paths + na_value: Value to use for missing values in the flux dataframe + copy_df_when_building_plot: Whether to copy the dataframe when building the plot. + This can be useful if the dataframe is going to be reused later. + exclude_zero_flux_pathways: Whether to exclude pathways that have zero flux across all conditions + + Returns: + A matplotlib Figure object containing the heatmap + + Raises: + ValueError: If `search_path` is True and `data` is not a Path """ if not isinstance(data, Path) and search_path: raise ValueError("If search_path is True, data must be a Path") @@ -263,7 +258,7 @@ def build_condition_vs_pathway_heatmap( return condition_vs_pathway(data=flux_df, save_filepath=save_filepath) -async def _main(): +def _main(): models = [ Path("/home/joshl/projects/ImmunoMetabolism/data/model_build/A/A_pDCs/A_pDCs_model_imat.json"), Path("/home/joshl/projects/ImmunoMetabolism/data/model_build/B/B_pDCs/B_pDCs_model_imat.json"), @@ -285,6 +280,4 @@ async def _main(): if __name__ == "__main__": - import asyncio - - asyncio.run(_main()) + _main() diff --git a/main/como/plot/heatmap.py b/main/como/plot/heatmap.py index cfa21c64..0d6e4e55 100644 --- a/main/como/plot/heatmap.py +++ b/main/como/plot/heatmap.py @@ -20,12 +20,14 @@ def condition_vs_pathway( ) -> plt.Figure: """Build a heatmap of fluxes through pathways across conditions. - :param data: Index values are conditions, column names are pathways - :param save_filepath: If provided, the resulting figure will be saved to this location - :param copy_df: Should the incoming dataframe be copied to prevent modifications to data? - :param exclude_zero_flux_pathways: Should pathways that have 0 flux across all rows be excluded? - - :return: The resulting `matpotlib.pyplt.Figure` object + Args: + data: Index values are conditions, column names are pathways + save_filepath: If provided, the resulting figure will be saved to this location + copy_df: Should the incoming dataframe be copied to prevent modifications to data? + exclude_zero_flux_pathways: Should pathways that have 0 flux across all rows be excluded? + + Returns: + The resulting `matpotlib.pyplt.Figure` object """ plot_df: pd.DataFrame = data.copy() if copy_df else data plot_df = plot_df.astype(np.float32) diff --git a/main/como/project.py b/main/como/project.py index b6a21bf9..19779940 100644 --- a/main/como/project.py +++ b/main/como/project.py @@ -9,8 +9,16 @@ class SingletonMeta(type): _instances: ClassVar[dict] = {} - def __call__(cls, *args, **kwargs): - """Validate that changes to the `__init__` argument do not affect the returned instance.""" + def __call__(cls, *args, **kwargs) -> SingletonMeta: + """Validate that changes to the `__init__` argument do not affect the returned instance. + + Args: + args: Positional arguments for the class constructor + kwargs: Keyword arguments for the class constructor + + Returns: + The singleton instance of the class + """ if cls not in cls._instances: instance = super().__call__(*args, **kwargs) cls._instances[cls] = instance @@ -56,7 +64,11 @@ def __init__( self.figures_dir.mkdir(parents=True, exist_ok=True) def update(self, **kwargs): - """Update a key in the config object.""" + """Update a key in the config object. + + Args: + kwargs: keyword argumentsto set for the singleton + """ for key, value in kwargs.items(): if hasattr(self, key): setattr(self, key, Path(value) if value else getattr(self, key)) @@ -64,18 +76,41 @@ def update(self, **kwargs): logger.warning(f"{key} is not a valid attribute of Config") def get_context_path(self, context_name: str, create: bool = True) -> Path: - """Get path for a specific context, optionally creating it.""" + """Get path for a specific context, optionally creating it. + + Args: + context_name: Name of the context (subdirectory). + create: Whether to create the directory if it doesn't exist. + + Returns: + Full path to the context directory. + """ path = self.result_dir / context_name if create: path.mkdir(parents=True, exist_ok=True) return path def get_r_path(self, path: Path) -> str: - """Convert a Path object to an R-compatible path string.""" + """Convert a Path object to an R-compatible path string. + + Args: + path: Path object to convert. + + Returns: + R-compatible path string. + """ return path.as_posix() def get_matrix_path(self, context_name: str, filename: str) -> Path: - """Get path for a matrix file in a specific context.""" + """Get path for a matrix file in a specific context. + + Arg: + context_name: Name of the context (subdirectory). + filename: Name of the matrix file. + + Returns: + Full path to the matrix file. + """ path = self.matrix_dir / context_name path.mkdir(parents=True, exist_ok=True) return path / filename diff --git a/main/como/proteomics/proteomics_preprocess.py b/main/como/proteomics/proteomics_preprocess.py index 86be1523..b2223da7 100644 --- a/main/como/proteomics/proteomics_preprocess.py +++ b/main/como/proteomics/proteomics_preprocess.py @@ -159,7 +159,7 @@ def _gather_data(self): url_count = 0 # Iterate through the URLs available - for url, study in zip(ftp_urls, studies): + for url, study in zip(ftp_urls, studies, strict=True): ftp_data: FTPManager.Reader = FTPManager.Reader(root_link=url, file_extensions=self._preferred_extensions) urls = list(ftp_data.files) @@ -167,7 +167,7 @@ def _gather_data(self): url_count += len(urls) # Iterate through all files and sizes found for url_## - for file, size in zip(urls, sizes): + for file, size in zip(urls, sizes, strict=True): self.file_information.append(FileInformation(cell_type=cell_type, download_url=file, file_size=size, study=study)) def print_download_size(self): @@ -205,12 +205,23 @@ def _set_replicate_numbers(self): current_info.set_replicate(replicate_value) def _collect_cell_type_information(self, cell_type: str) -> list[FileInformation]: - """Collect all FileInformation objects of a given cell type.""" + """Collect all FileInformation objects of a given cell type. + + Arg: + cell_type: The cell type to collect information for. + + Returns: + A list of FileInformation objects matching the given cell type. + """ return [information for information in self.file_information if information.cell_type == cell_type] def parse_args() -> argparse.Namespace: - """Parse arguments from the command line.""" + """Parse arguments from the command line. + + Returns: + An argparse.Namespace object containing the parsed arguments. + """ parser = argparse.ArgumentParser( prog="proteomics_preprocess.py", description="Download and analyze proteomics data from proteomeXchange\n" diff --git a/main/como/proteomics_gen.py b/main/como/proteomics_gen.py index 102490ba..012486a4 100644 --- a/main/como/proteomics_gen.py +++ b/main/como/proteomics_gen.py @@ -17,7 +17,14 @@ # Load Proteomics def process_proteomics_data(path: Path) -> pd.DataFrame: - """Load proteomics data from a given context and filename.""" + """Load proteomics data from a given context and filename. + + Args: + path: Path to the proteomics data file (CSV format). + + Returns: + pd.DataFrame: Processed proteomics data with 'gene_symbol' column exploded. + """ # Preprocess data, drop na, duplicate ';' in symbol, matrix: pd.DataFrame = pd.read_csv(path) if "gene_symbol" not in matrix.columns: @@ -35,7 +42,15 @@ def process_proteomics_data(path: Path) -> pd.DataFrame: # read map to convert to entrez async def load_gene_symbol_map(gene_symbols: list[str], entrez_map: Path | None = None): - """Add descirption....""" + """Load a mapping from gene symbols to Entrez IDs. + + Args: + gene_symbols (list[str]): List of gene symbols to map. + entrez_map (Path | None): Optional path to a CSV file containing precomputed mappings. + + Returns: + pd.DataFrame: DataFrame with gene symbols as index and corresponding Entrez IDs. + """ if entrez_map and entrez_map.exists(): df = pd.read_csv(entrez_map, index_col="gene_symbol") else: @@ -122,8 +137,16 @@ def to_bool_context(context_name, group_ratio, hi_group_ratio, group_names): # read data from csv files -def load_proteomics_tests(filename, context_name): - """Load statistical test results.""" +def load_proteomics_tests(filename, context_name) -> tuple[str, pd.DataFrame]: + """Load statistical test results. + + Arg: + filename (str): The name of the file to load. + context_name (str): The context name for the data. + + Returns: + tuple: A tuple containing the context name and the loaded data as a pandas DataFrame. + """ config = Config() def load_empty_dict(): @@ -187,7 +210,7 @@ async def proteomics_gen( error=FileNotFoundError, level=LogLevel.ERROR, ) - if matrix_filepath.suffix not in {".csv"}: + if matrix_filepath.suffix != ".csv": _log_and_raise_error( f"Matrix file must be a csv file at {matrix_filepath}", error=FileNotFoundError, diff --git a/main/como/proteomics_preprocessing.py b/main/como/proteomics_preprocessing.py index 21f38a78..39d4c85c 100644 --- a/main/como/proteomics_preprocessing.py +++ b/main/como/proteomics_preprocessing.py @@ -29,7 +29,15 @@ class ZResult: def z_score_calc(abundance: pd.DataFrame, min_thresh: int) -> ZResult: - """Calculate Z-scores for protein abundance data.""" + """Calculate Z-scores for protein abundance data. + + Arg: + abundance: DataFrame with protein abundance data. + min_thresh: Minimum threshold for abundance values to be considered. + + Returns: + A ZResult object containing Z-score transformed data and related statistics. + """ values = abundance.values.copy() + 1 log_abundance_filt = np.log2(values[values > min_thresh]).reshape((len(abundance), len(abundance.columns))) log_abundance = np.log2(values) @@ -70,7 +78,17 @@ def z_score_calc(abundance: pd.DataFrame, min_thresh: int) -> ZResult: def lighten_color(red: int, green: int, blue: int, factor: float = 0.5) -> str: - """Lighten a color by a given factor.""" + """Lighten a color by a given factor. + + Args: + red: Red component (0-255). + green: Green component (0-255). + blue: Blue component (0-255). + factor: Factor by which to lighten the color (0.0 to 1.0). + + Returns: + A string representing the lightened color in RGB format. + """ # Convert RGB to HLS hue, lightness, saturation = colorsys.rgb_to_hls(red / 255.0, green / 255.0, blue / 255.0) @@ -84,7 +102,17 @@ def lighten_color(red: int, green: int, blue: int, factor: float = 0.5) -> str: # Plotting function def plot_gaussian_fit(z_results: ZResult, facet_titles: bool = True, x_min: int = -4) -> go.Figure: - """Plot Gaussian fit for Z-score transformed data.""" + """Plot Gaussian fit for Z-score transformed data. + + Arg: + z_results: The results from the Z-score calculation. + facet_titles: Whether to show titles for each facet. + x_min: Minimum x-axis value for the plots. + + Returns: + A Plotly Figure object containing the Gaussian fit plots. + + """ zfpkm = z_results.zfpkm x_range = z_results.x_range density = z_results.density diff --git a/main/como/rnaseq_gen.py b/main/como/rnaseq_gen.py index 6df3221f..0effe2e4 100644 --- a/main/como/rnaseq_gen.py +++ b/main/como/rnaseq_gen.py @@ -4,12 +4,13 @@ import sys import time from collections import namedtuple +from collections.abc import Callable from concurrent.futures import Future, ProcessPoolExecutor, as_completed from dataclasses import dataclass, field from enum import Enum from io import TextIOWrapper from pathlib import Path -from typing import Callable, NamedTuple +from typing import NamedTuple import matplotlib.pyplot as plt import numpy as np @@ -131,9 +132,12 @@ def genefilter(data: pd.DataFrame | npt.NDArray, filter_func: Callable[[npt.NDAr This code is based on the `genefilter` function found in R's `genefilter` package: https://www.rdocumentation.org/packages/genefilter/versions/1.54.2/topics/genefilter - :param data: The data to filter - :param filter_func: THe function to filter the data by - :return: A NumPy array of the filtered data. + Arg: + data: The data to filter, either a Pandas DataFrame or a NumPy array. + filter_func: THe function to filter the data by + + Returns: + A NumPy array of the filtered data. """ if not isinstance(data, (pd.DataFrame, npt.NDArray)): _log_and_raise_error( @@ -154,10 +158,13 @@ async def _build_matrix_results( ) -> _ReadMatrixResults: """Read the counts matrix and returns the results. - :param matrix: The gene counts matrix to process - :param metadata_df: The configuration dataframe related to the current context - :param taxon: The NCBI Taxon ID - :return: A dataclass `ReadMatrixResults` + Arg: + matrix: The gene counts matrix to process + metadata_df: The configuration dataframe related to the current context + taxon: The NCBI Taxon ID + + Returns: + A dataclass `ReadMatrixResults` """ matrix.dropna(subset="ensembl_gene_id", inplace=True) conversion = await ensembl_to_gene_id_and_symbol(ids=matrix["ensembl_gene_id"].tolist(), taxon=taxon) @@ -226,7 +233,14 @@ async def _build_matrix_results( def calculate_tpm(metrics: NamedMetrics) -> NamedMetrics: - """Calculate the Transcripts Per Million (TPM) for each sample in the metrics dictionary.""" + """Calculate the Transcripts Per Million (TPM) for each sample in the metrics dictionary. + + Args: + metrics: A dictionary of study metrics to calculate TPM for. + + Returns: + A dictionary of study metrics with TPM calculated. + """ for sample in metrics: count_matrix = metrics[sample].count_matrix @@ -242,7 +256,15 @@ def calculate_tpm(metrics: NamedMetrics) -> NamedMetrics: def _calculate_fpkm(metrics: NamedMetrics, scale: int = 1e6) -> NamedMetrics: - """Calculate the Fragments Per Kilobase of transcript per Million mapped reads (FPKM) for each sample in the metrics dictionary.""" + """Calculate the Fragments Per Kilobase of transcript per Million mapped reads (FPKM) for each sample in the metrics dictionary. + + Args: + metrics: A dictionary of study metrics to calculate FPKM for. + scale: The scaling factor for normalization (default is 1e6). + + Returns: + A dictionary of study metrics with FPKM calculated. + """ for study in metrics: matrix_values = [] @@ -333,7 +355,7 @@ def _zfpkm_calculation( - Standard deviation is estimated based on the assumption that the right tail of the distribution This represents expressed genes) can be approximated by a half-normal distribution - zFPKM Transformation + zFPKM Transformation - Centers disbribution around 0 and scales it by the standard deviation. This makes it easier to compare gene expression across different samples - Represents the number of standard deviations away from the mean of the "inactive" gene distribution @@ -342,6 +364,19 @@ def _zfpkm_calculation( - Research shows that a zFPKM value of -3 or greater can be used as a threshold for calling a gene as "active" and/or "expressed" : https://doi.org/10.1186/1471-2164-14-778 + + Args: + column: A Pandas Series containing FPKM values for a single sample. + peak_parameters: Parameters for peak identification in zFPKM calculation. + bandwidth: The bandwidth for kernel density estimation in zFPKM calculation. + + Returns: + A named tuple containing: + - zfpkm: A Pandas Series of zFPKM values for the input sample. + - density: A named tuple containing the x and y values of the KDE. + - mu: The mean of the "inactive" gene distribution. + - std_dev: The estimated standard deviation of the "inactive" gene distribution. + - max_fpkm: The maximum FPKM value at the identified peak. """ values: npt.NDArray = column.values # replace na values with 0 @@ -374,7 +409,19 @@ def zfpkm_transform( bandwidth: int, update_every_percent: float = 0.1, ) -> tuple[dict[str, _ZFPKMResult], DataFrame]: - """Perform zFPKM calculation/transformation.""" + """Perform zFPKM calculation/transformation. + + Args: + fpkm_df: A DataFrame containing FPKM values with genes as rows and samples as columns. + peak_parameters: Parameters for peak identification in zFPKM calculation. + bandwidth: The bandwidth for kernel density estimation in zFPKM calculation. + update_every_percent: Frequency of progress updates as a decimal between 0 and 1 (e.g., 0.1 for every 10%). + + Returns: + A tuple containing: + - A dictionary of intermediate results for each sample. + - A DataFrame of zFPKM values with the same shape as the input fpkm_df. + """ if update_every_percent > 1: logger.warning(f"update_every_percent should be a decimal value between 0 and 1; got: {update_every_percent} - will convert to percentage") update_every_percent /= 100 @@ -459,9 +506,11 @@ def zfpkm_plot(results, *, output_png_filepath: Path, plot_xfloor: int = -4): mega_df.columns = pd.Series(data=["sample_name", "log2fpkm", "fpkm_density", "fitted_density_scaled"]) mega_df = mega_df.melt(id_vars=["log2fpkm", "sample_name"], var_name="source", value_name="density") + fig: plt.Figure + axes: plt.Axes fig, axes = plt.subplots(nrows=len(results), ncols=1, figsize=(8, 4 * len(results))) if len(results) == 1: - axes = [axes] + axes: list[plt.Axes] = [axes] for i, sample_name in enumerate(results): sample_data = mega_df[mega_df["sample_name"] == sample_name] @@ -476,15 +525,22 @@ def zfpkm_plot(results, *, output_png_filepath: Path, plot_xfloor: int = -4): axis.set_ylabel("density [scaled]") axis.legend(title="Source") - plt.tight_layout() + fig.tight_layout() if output_png_filepath.suffix != ".png": logger.warning(f"Output filepath did not end in '.png', setting to '.png' now. Got: '{output_png_filepath.suffix}'") output_png_filepath = output_png_filepath.with_suffix(".png") - plt.savefig(output_png_filepath) + fig.savefig(output_png_filepath) def calculate_z_score(metrics: NamedMetrics) -> NamedMetrics: - """Calculate the z-score for each sample in the metrics dictionary.""" + """Calculate the z-score for each sample in the metrics dictionary. + + Args: + metrics: A dictionary of study metrics to calculate z-scores for. + + Returns: + A dictionary of study metrics with z-scores calculated. + """ for sample in metrics: log_matrix = np.log(metrics[sample].normalization_matrix) z_matrix = pd.DataFrame(data=sklearn.preprocessing.scale(log_matrix, axis=1), columns=metrics[sample].sample_names) @@ -499,7 +555,17 @@ def cpm_filter( filtering_options: _FilteringOptions, prep: RNAType, ) -> NamedMetrics: - """Apply Counts Per Million (CPM) filtering to the count matrix for a given sample.""" + """Apply Counts Per Million (CPM) filtering to the count matrix for a given sample. + + Args: + context_name: The name of the context being processed. + metrics: A dictionary of study metrics to filter. + filtering_options: Options for filtering the count matrix. + prep: The RNA preparation type. + + Returns: + A dictionary of filtered study metrics. + """ config = Config() n_exp = filtering_options.replicate_ratio n_top = filtering_options.high_replicate_ratio @@ -543,7 +609,15 @@ def cpm_filter( def tpm_quantile_filter(*, metrics: NamedMetrics, filtering_options: _FilteringOptions) -> NamedMetrics: - """Apply quantile-based filtering to the TPM matrix for a given sample.""" + """Apply quantile-based filtering to the TPM matrix for a given sample. + + Args: + metrics: A dictionary of study metrics to filter. + filtering_options: Options for filtering the count matrix. + + Returns: + A dictionary of filtered study metrics. + """ # TODO: Write the TPM matrix to disk n_exp = filtering_options.replicate_ratio @@ -572,13 +646,13 @@ def tpm_quantile_filter(*, metrics: NamedMetrics, filtering_options: _FilteringO top_genes: npt.NDArray[bool] = genefilter(boolean_expression, top_func) # Only keep `entrez_gene_ids` that pass `min_genes` - metric.entrez_gene_ids = [gene for gene, keep in zip(entrez_ids, min_genes) if keep] - metric.gene_sizes = np.array(gene for gene, keep in zip(gene_size, min_genes) if keep) + metric.entrez_gene_ids = [gene for gene, keep in zip(entrez_ids, min_genes, strict=True) if keep] + metric.gene_sizes = np.array(gene for gene, keep in zip(gene_size, min_genes, strict=True) if keep) metric.count_matrix = metric.count_matrix.iloc[min_genes, :] metric.normalization_matrix = metrics[sample].normalization_matrix.iloc[min_genes, :] - keep_top_genes = [gene for gene, keep in zip(entrez_ids, top_genes) if keep] - metric.high_confidence_entrez_gene_ids = [gene for gene, keep in zip(entrez_ids, keep_top_genes) if keep] + keep_top_genes = [gene for gene, keep in zip(entrez_ids, top_genes, strict=True) if keep] + metric.high_confidence_entrez_gene_ids = [gene for gene, keep in zip(entrez_ids, keep_top_genes, strict=True) if keep] metrics = calculate_z_score(metrics) @@ -595,7 +669,20 @@ def zfpkm_filter( bandwidth: int, output_png_filepath: Path | None, ) -> NamedMetrics: - """Apply zFPKM filtering to the FPKM matrix for a given sample.""" + """Apply zFPKM filtering to the FPKM matrix for a given sample. + + Args: + metrics: A dictionary of study metrics to filter. + filtering_options: Options for filtering the count matrix. + calculate_fpkm: Whether to calculate FPKM from counts. + force_zfpkm_plot: Whether to force plotting of zFPKM results even if there are many samples. + peak_parameters: Parameters for peak identification in zFPKM calculation. + bandwidth: The bandwidth for kernel density estimation in zFPKM calculation. + output_png_filepath: Optional filepath to save the zFPKM plot. + + Returns: + A dictionary of filtered study metrics. + """ min_sample_expression = filtering_options.replicate_ratio high_confidence_sample_expression = filtering_options.high_replicate_ratio cut_off = filtering_options.cut_off @@ -628,13 +715,13 @@ def zfpkm_filter( min_samples = round(min_sample_expression * len(zfpkm_df.columns)) min_func = k_over_a(min_samples, cut_off) min_genes: npt.NDArray[bool] = genefilter(zfpkm_df, min_func) - metric.entrez_gene_ids = [gene for gene, keep in zip(metric.entrez_gene_ids, min_genes) if keep] + metric.entrez_gene_ids = [gene for gene, keep in zip(metric.entrez_gene_ids, min_genes, strict=True) if keep] # determine which genes are confidently expressed top_samples = round(high_confidence_sample_expression * len(zfpkm_df.columns)) top_func = k_over_a(top_samples, cut_off) top_genes: npt.NDArray[bool] = genefilter(zfpkm_df, top_func) - metric.high_confidence_entrez_gene_ids = [gene for gene, keep in zip(metric.entrez_gene_ids, top_genes) if keep] + metric.high_confidence_entrez_gene_ids = [gene for gene, keep in zip(metric.entrez_gene_ids, top_genes, strict=True) if keep] return metrics @@ -651,7 +738,22 @@ def filter_counts( bandwidth: int, output_png_filepath: Path | None = None, ) -> NamedMetrics: - """Filter the count matrix based on the specified technique.""" + """Filter the count matrix based on the specified technique. + + Args: + context_name: The name of the context being processed. + metrics: A dictionary of study metrics to filter. + technique: The filtering technique to use. + filtering_options: Options for filtering the count matrix. + prep: The RNA preparation type. + force_zfpkm_plot: Whether to force plotting of zFPKM results even if there are many samples. + peak_parameters: Parameters for peak identification in zFPKM calculation. + bandwidth: The bandwidth for kernel density estimation in zFPKM calculation. + output_png_filepath: Optional filepath to save the zFPKM plot. + + Returns: + A dictionary of filtered study metrics. + """ match technique: case FilteringTechnique.CPM: return cpm_filter(context_name=context_name, metrics=metrics, filtering_options=filtering_options, prep=prep) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index 8a843c4b..2a219b5d 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -196,7 +196,7 @@ def _organize_gene_counts_files(data_dir: Path) -> list[_StudyMetrics]: # For each study, collect gene count files, fragment files, insert size files, layouts, and strandedness information study_metrics: list[_StudyMetrics] = [] - for gene_dir, strand_dir in zip(gene_counts_directories, strandedness_directories): + for gene_dir, strand_dir in zip(gene_counts_directories, strandedness_directories, strict=True): count_files = list(gene_dir.glob("*.tab")) strand_files = list(strand_dir.glob("*.txt")) if len(count_files) == 0: @@ -328,7 +328,17 @@ async def _write_counts_matrix( output_counts_matrix_filepath: Path, rna: RNAType, ) -> pd.DataFrame: - """Create a counts matrix file by reading gene counts table(s).""" + """Create a counts matrix file by reading gene counts table(s). + + Args: + config_df: Configuration DataFrame containing sample information. + como_context_dir: Path to the COMO_input directory containing gene count files. + output_counts_matrix_filepath: Path where the output counts matrix CSV will be saved. + rna: RNAType enum indicating whether to process 'trna' or 'mrna' samples. + + Returns: + A pandas DataFrame representing the final counts matrix. + """ study_metrics = _organize_gene_counts_files(data_dir=como_context_dir) counts: list[pd.DataFrame] = await asyncio.gather(*[_create_sample_counts_matrix(metric) for metric in study_metrics]) rna_specific_sample_names = set(config_df.loc[config_df["library_prep"] == rna.value, "sample_name"].tolist()) @@ -358,7 +368,20 @@ async def _create_config_df( # noqa: C901 """Create configuration sheet. The configuration file created is based on the gene counts matrix. - If using zFPKM normalization technique, mean fragment lengths will be fetched + If using zFPKM normalization technique, mean fragment lengths will be fetched + + Args: + context_name: Name of the context, used as a prefix for sample names. + como_context_dir: Path to the COMO_input directory containing subdirectories for + gene counts, layouts, strandedness, fragment sizes, and prep methods. + gene_count_dirname: Name of the subdirectory containing gene count files. + layout_dirname: Name of the subdirectory containing layout files. + strandedness_dirname: Name of the subdirectory containing strandedness files. + fragment_sizes_dirname: Name of the subdirectory containing fragment size files. + prep_method_dirname: Name of the subdirectory containing library preparation method files. + + Returns: + A pandas DataFrame representing the configuration sheet. """ label_regex: Final = re.compile(r"(?PS\d{1,3})(?PR\d{1,3})(?Pr\d{1,3})?") gene_counts: list[Path] = list((como_context_dir / gene_count_dirname).rglob("*.tab")) diff --git a/main/como/utils.py b/main/como/utils.py index 3a3d37ce..27d18c23 100644 --- a/main/como/utils.py +++ b/main/como/utils.py @@ -1,5 +1,6 @@ from __future__ import annotations +import asyncio import contextlib import io import sys @@ -8,6 +9,7 @@ from pathlib import Path from typing import Literal +import aiofiles import numpy.typing as npt import pandas as pd import scanpy as sc @@ -33,7 +35,11 @@ def stringlist_to_list(stringlist: str | list[str]) -> list[str]: If '[' and ']' are present in the first and last items of the list, assume we are using the "old" method of providing context names - :param stringlist: The "string list" gathered from the command line. Example input: "['mat', 'xml', 'json']" + Args: + stringlist: The "string list" gathered from the command line. Example input: "['mat', 'xml', 'json']" + + Returns: + A list of strings. Example output: ['mat', 'xml', 'json'] """ if isinstance(stringlist, list): return stringlist @@ -66,11 +72,14 @@ def split_gene_expression_data( ): """Split the gene expression data into single-gene and multiple-gene names. - :param expression_data: The gene expression data to map - :param identifier_column: The column containing the gene identifiers, either 'ensembl_gene_id' or 'entrez_gene_id' - :param recon_algorithm: The recon algorithm used to generate the gene expression data - :param ensembl_as_index: Should the 'ensembl_gene_id' column be set as the index - :return: + Arg: + expression_data: The gene expression data to map + identifier_column: The column containing the gene identifiers, either 'ensembl_gene_id' + recon_algorithm: The recon algorithm used to generate the gene expression data + ensembl_as_index: Should the 'ensembl_gene_id' column be set as + + Returns: + A pandas DataFrame with the split gene expression data """ expression_data.columns = [c.lower() for c in expression_data.columns] if recon_algorithm in {Algorithm.IMAT, Algorithm.TINIT}: @@ -108,11 +117,14 @@ async def _format_determination( ) -> pd.DataFrame: """Determine the data type of the given input values (i.e., Entrez Gene ID, Gene Symbol, etc.). - :param biodbnet: The BioDBNet to use for deter - :param requested_output: The data type to generate (of type `Output`) - :param input_values: The input values to determine - :param taxon: The Taxon ID - :return: A pandas DataFrame + Args: + biodbnet: The BioDBNet to use for determination + requested_output: The data type to generate (of type `Output`) + input_values: The input values to determine + taxon: The Taxon ID + + Returns: + A pandas DataFrame """ requested_output = [requested_output] if isinstance(requested_output, Output) else requested_output coercion = (await biodbnet.db_find(values=input_values, output_db=requested_output, taxon=taxon)).drop(columns=["Input Type"]) @@ -131,10 +143,13 @@ async def _read_file( None may be provided to this function so that `asyncio.gather` can safely be used on all sources (trna, mrna, scrna, proteomics) without needing to check if the user has provided those sources - :param path: The path to read from - :param kwargs: Additional arguments to pass to pandas.read_csv, pandas.read_excel, - or scanpy.read_h5ad, depending on the filepath provided - :return: None, or a pandas DataFrame or AnnData + Args: + path: The path to read from + h5ad_as_df: If True and the file is an h5ad, return a DataFrame of the .X matrix instead of an AnnData object + kwargs: Additional arguments to pass to pandas.read_csv, pandas.read_excel, or scanpy.read_h5ad, depending on the filepath provided + + Returns: + None, or a pandas DataFrame or AnnData """ if isinstance(path, (pd.DataFrame, sc.AnnData)): return path @@ -152,13 +167,13 @@ async def _read_file( case ".csv" | ".tsv" | ".txt": if "sep" not in kwargs: kwargs.setdefault("sep", "," if path.suffix == ".csv" else "\t") - with path.open("r") as i_stream: - content = i_stream.read() + async with aiofiles.open(path) as i_stream: + content = await i_stream.read() return pd.read_csv(io.StringIO(content), **kwargs) case ".xlsx" | ".xls": - return pd.read_excel(path, **kwargs) + return await asyncio.to_thread(pd.read_excel, path, **kwargs) case ".h5ad": - adata: sc.AnnData = sc.read_h5ad(path, **kwargs) + adata: sc.AnnData = await asyncio.to_thread(sc.read_h5ad, path, **kwargs) if h5ad_as_df: df = adata.to_df().T df.index.name = "gene_symbol" @@ -200,7 +215,14 @@ async def get_missing_gene_data(values: list[str] | pd.DataFrame, taxon_id: int def _listify(value): - """Convert items into a list.""" + """Convert items into a list. + + Args: + value: The value to convert to a list + + Returns: + A list containing `value`, unless it is already a list + """ return [value] if not isinstance(value, list) else value diff --git a/ruff.toml b/ruff.toml index 309140fa..509a1911 100644 --- a/ruff.toml +++ b/ruff.toml @@ -1,6 +1,7 @@ line-length = 150 extend-include = ["docs/**/*.py", "tests/**/*.py", "**/*.ipynb"] + [format] quote-style = "double" docstring-code-format = true @@ -41,6 +42,9 @@ ignore = [ "F401", # allow unused imports ] +[lint.pydocstyle] +convention = "google" + [lint.per-file-ignores] "tests/*" = [ "D101", # allow undocumented public class diff --git a/tests/unit/test_data_types.py b/tests/unit/test_data_types.py index d5e1277a..f5023e08 100644 --- a/tests/unit/test_data_types.py +++ b/tests/unit/test_data_types.py @@ -4,7 +4,7 @@ def test_source_types(): """Validate that source types always go in the order of 'trna', 'mrna', 'scrna', 'proteomics'.""" expected_order = ["trna", "mrna", "scrna", "proteomics"] - for expected, source in zip(expected_order, SourceTypes): + for expected, source in zip(expected_order, SourceTypes, strict=True): expected: str source: SourceTypes assert expected == source.value diff --git a/tests/unit/test_rnaseq_preprocess.py b/tests/unit/test_rnaseq_preprocess.py index c0d49c2e..bf834aea 100644 --- a/tests/unit/test_rnaseq_preprocess.py +++ b/tests/unit/test_rnaseq_preprocess.py @@ -40,7 +40,7 @@ async def test_build_from_tab_valid_file(self): @pytest.mark.asyncio async def test_build_from_tab_invalid_file(self): """Validate error on invalid file.""" - with pytest.raises(ValueError, match="Building STAR information requires a '.tab' file"): + with pytest.raises(ValueError, match="Building STAR information requires a '\.tab' file"): await _STARinformation.build_from_tab(TestSTARInformation.invalid_data) From df84aeaf2b4623dd0afdf6e04f8f812ea5d16aa7 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 5 Sep 2025 13:29:37 -0500 Subject: [PATCH 238/265] fix: invalid collection of gene counts Signed-off-by: Josh Loecker --- main/como/rnaseq_preprocess.py | 2 +- tests/unit/test_rnaseq_preprocess.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index 2a219b5d..93ffe2f3 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -160,7 +160,7 @@ async def _read_text(path: Path | None, *, default: str, lower: bool = False) -> def _sample_name_from_filepath(file: Path) -> str: - return re.search(r".+_S\d+R\d+", file.stem).group() + return re.search(r".+_S\d+R\d+(r\d+)?", file.stem).group() def _require_one(paths: list[Path], kind: Literal["layout", "strand", "preparation", "fragment"], label: str) -> Path | None: diff --git a/tests/unit/test_rnaseq_preprocess.py b/tests/unit/test_rnaseq_preprocess.py index bf834aea..ce799657 100644 --- a/tests/unit/test_rnaseq_preprocess.py +++ b/tests/unit/test_rnaseq_preprocess.py @@ -40,7 +40,7 @@ async def test_build_from_tab_valid_file(self): @pytest.mark.asyncio async def test_build_from_tab_invalid_file(self): """Validate error on invalid file.""" - with pytest.raises(ValueError, match="Building STAR information requires a '\.tab' file"): + with pytest.raises(ValueError, match=r"Building STAR information requires a '\.tab' file"): await _STARinformation.build_from_tab(TestSTARInformation.invalid_data) @@ -70,7 +70,7 @@ async def test_process_first_multirun_sample(strand_filepath: Path, all_gene_cou result: pd.DataFrame = await _process_first_multirun_sample(strand_filepath, all_gene_count_filepaths) assert result.columns[0] == "ensembl_gene_id" assert len(result.columns) == 2 - assert result.columns[1] in strand_filepath.as_posix() + assert result.columns.tolist()[1] in strand_filepath.as_posix() def test_pack_filepaths(packed_filepaths: PackedFilepaths): From bcb668985f03996d9ee562a2daa62e32b564f3ea Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Fri, 5 Sep 2025 13:49:19 -0500 Subject: [PATCH 239/265] fix(rnaseq_preprocess): ensure correct order of async file reads and improve data handling Signed-off-by: Josh Loecker --- main/como/rnaseq_preprocess.py | 40 ++++++++++++++++------------ main/como/utils.py | 6 ++--- tests/unit/test_rnaseq_preprocess.py | 1 + 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index 93ffe2f3..d5e10db6 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -51,23 +51,29 @@ async def build_from_tab(cls, filepath: Path) -> _STARinformation: ) async with aiofiles.open(filepath) as i_stream: - unmapped, multimapping, no_feature, ambiguous = await asyncio.gather( - *[i_stream.readline(), i_stream.readline(), i_stream.readline(), i_stream.readline()] - ) - - num_unmapped = [int(i) for i in unmapped.rstrip("\n").split("\t")[1:]] - num_multimapping = [int(i) for i in multimapping.rstrip("\n").split("\t")[1:]] - num_no_feature = [int(i) for i in no_feature.rstrip("\n").split("\t")[1:]] - num_ambiguous = [int(i) for i in ambiguous.rstrip("\n").split("\t")[1:]] - remainder = await i_stream.read() - - df = await _read_file(StringIO(remainder), sep="\t", header=None) - df.columns = [ - "ensembl_gene_id", - "unstranded_rna_counts", - "first_read_transcription_strand", - "second_read_transcription_strand", - ] + # Cannot use `asyncio.gather()` here because the order of execution is not guaranteed + unmapped = await i_stream.readline() + multimapping = await i_stream.readline() + no_feature = await i_stream.readline() + ambiguous = await i_stream.readline() + + num_unmapped = [int(i) for i in unmapped.removesuffix("\n").split("\t")[1:]] + num_multimapping = [int(i) for i in multimapping.removesuffix("\n").split("\t")[1:]] + num_no_feature = [int(i) for i in no_feature.removesuffix("\n").split("\t")[1:]] + num_ambiguous = [int(i) for i in ambiguous.removesuffix("\n").split("\t")[1:]] + + df = await _read_file( + filepath, + sep="\t", + header=None, + skiprows=4, + names=[ + "ensembl_gene_id", + "unstranded_rna_counts", + "first_read_transcription_strand", + "second_read_transcription_strand", + ], + ) df = df[~df["ensembl_gene_id"].isna()] return _STARinformation( num_unmapped=num_unmapped, diff --git a/main/como/utils.py b/main/como/utils.py index 27d18c23..a7390fed 100644 --- a/main/como/utils.py +++ b/main/como/utils.py @@ -164,12 +164,10 @@ async def _read_file( return pd.read_csv(path, **kwargs) match path.suffix: - case ".csv" | ".tsv" | ".txt": + case ".csv" | ".tsv" | ".txt" | ".tab": if "sep" not in kwargs: kwargs.setdefault("sep", "," if path.suffix == ".csv" else "\t") - async with aiofiles.open(path) as i_stream: - content = await i_stream.read() - return pd.read_csv(io.StringIO(content), **kwargs) + return await asyncio.to_thread(pd.read_csv, path, **kwargs) case ".xlsx" | ".xls": return await asyncio.to_thread(pd.read_excel, path, **kwargs) case ".h5ad": diff --git a/tests/unit/test_rnaseq_preprocess.py b/tests/unit/test_rnaseq_preprocess.py index ce799657..978eb2c5 100644 --- a/tests/unit/test_rnaseq_preprocess.py +++ b/tests/unit/test_rnaseq_preprocess.py @@ -31,6 +31,7 @@ class TestSTARInformation: async def test_build_from_tab_valid_file(self): """Validate building STAR information object.""" star: _STARinformation = await _STARinformation.build_from_tab(TestSTARInformation.valid_data) + assert len(star.gene_names) == len(star.count_matrix) == 61541 assert len(star.num_unmapped) == 3 assert len(star.num_multimapping) == 3 From feb7d11c5afcb9b7c7112c394b60d4e931441669 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Wed, 10 Sep 2025 14:57:37 -0500 Subject: [PATCH 240/265] chore: add type hint Signed-off-by: Josh Loecker --- tests/unit/test_rnaseq_preprocess.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/unit/test_rnaseq_preprocess.py b/tests/unit/test_rnaseq_preprocess.py index 978eb2c5..6b3419c2 100644 --- a/tests/unit/test_rnaseq_preprocess.py +++ b/tests/unit/test_rnaseq_preprocess.py @@ -7,7 +7,6 @@ from como.rnaseq_preprocess import ( _organize_gene_counts_files, _process_first_multirun_sample, - _process_standard_replicate, _sample_name_from_filepath, _STARinformation, _StudyMetrics, @@ -28,7 +27,7 @@ class TestSTARInformation: invalid_data = Path("main/data/COMO_input/naiveB/fragmentSizes/S1/naiveB_S1R1_fragment_size.txt").resolve() @pytest.mark.asyncio - async def test_build_from_tab_valid_file(self): + async def test_build_from_tab_valid_file(self) -> None: """Validate building STAR information object.""" star: _STARinformation = await _STARinformation.build_from_tab(TestSTARInformation.valid_data) @@ -51,8 +50,8 @@ def test_sample_name_from_filepath(any_como_input_filepath: Path): def test_organize_gene_counts_files(como_input_data_directory: Path): - metrics: list[_StudyMetrics] = _organize_gene_counts_files(como_input_data_directory) - for metric in metrics: + metric: _StudyMetrics + for metric in _organize_gene_counts_files(como_input_data_directory): assert len(metric.sample_names) == metric.num_samples == len(metric.count_files) == len(metric.strand_files) for file in metric.count_files: From dbf12f499ac29c2754f18baed8e625491c353bb5 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Wed, 10 Sep 2025 14:58:43 -0500 Subject: [PATCH 241/265] refactor: use python optional-groups instead of uv dependency-groups Signed-off-by: Josh Loecker --- pyproject.toml | 38 ++++---- uv.lock | 232 ++++++++++++++++++++----------------------------- 2 files changed, 111 insertions(+), 159 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 739f2d61..95f89ba8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,19 +28,27 @@ dependencies = [ ] [project.optional-dependencies] -gurobi = [ "gurobipy<14" ] -interactive = [ +gurobi = [ + "gurobipy<14", +] +interactive = [ "ipython>=8.0.0", "jupyterlab>=4.3.2" ] dev = [ - "commitlint>=1.3.0", - "pytest-asyncio>=0.24.0", - "pytest>=8.3.3", - "ruff>=0.8.0", - "hypothesis>=6.122.1", - "pytest-cov>=6.0.0", - "commitizen>=4.1.0", + "commitizen>=4.8.3", + "commitlint>=1.3.1", + "como", + "hatchling>=1.27.0", + "pandas-stubs>=2.3.2.250827", + "pre-commit>=4.2.0", + "pyright>=1.1.405", + "pytest>=8.4.1", + "pytest-asyncio>=1.1.0", + "pytest-cov>=6.2.1", + "ruff>=0.12.11", + "scipy-stubs>=1.16.1.1", + "types-aiofiles>=24.1.0.20250822", ] @@ -54,7 +62,7 @@ packages = ["main/como"] allow-direct-references = true [tool.pytest.ini_options] -pythonpath = [ "main/src" ] +pythonpath = ["main/src"] [tool.commitizen] name = "cz_conventional_commits" @@ -64,13 +72,5 @@ version_provider = "pep621" update_changelog_on_bump = true [tool.uv.sources] -como = { workspace = true } cobra = { git = "https://github.com/ripaul/cobrapy", rev = "hopsy-backend" } - -[dependency-groups] -dev = [ - "como", - "pandas-stubs>=2.3.2.250827", - "pre-commit>=4.2.0", - "scipy-stubs>=1.16.1.1", -] +como = { workspace = true } diff --git a/uv.lock b/uv.lock index e2c23f0c..8d226ed8 100644 --- a/uv.lock +++ b/uv.lock @@ -149,27 +149,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f8/ed/e97229a566617f2ae958a6b13e7cc0f585470eac730a73e9e82c32a3cdd2/arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80", size = 66419, upload-time = "2023-09-30T22:11:16.072Z" }, ] -[[package]] -name = "arviz" -version = "0.22.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "h5netcdf" }, - { name = "matplotlib" }, - { name = "numpy" }, - { name = "packaging" }, - { name = "pandas" }, - { name = "scipy" }, - { name = "setuptools" }, - { name = "typing-extensions" }, - { name = "xarray" }, - { name = "xarray-einstats" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/31/24/727d666e137f0b8c4a4fdc3dc91484ab2ed1206ac61733b2688efa85b5e7/arviz-0.22.0.tar.gz", hash = "sha256:d9df7592f1ce77ce69f7504dba13f8d550204c49c23e54849861dbcb2c640954", size = 1591019, upload-time = "2025-07-09T10:07:21.525Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/81/38/5a3ee119be7f9f94f03a7626ee8edc52c9c9a9720cb020fa1f01fc87d4f2/arviz-0.22.0-py3-none-any.whl", hash = "sha256:336a3a4b1aa981997945f9ca104ca9f827e9c943f13760b18bf645ee5b12d56d", size = 1672062, upload-time = "2025-07-09T10:07:19.643Z" }, -] - [[package]] name = "asttokens" version = "3.0.0" @@ -457,8 +436,6 @@ dependencies = [ { name = "cobamp" }, { name = "cobra" }, { name = "fast-bioservices" }, - { name = "gurobipy" }, - { name = "hopsy" }, { name = "kaleido" }, { name = "loguru" }, { name = "numpy" }, @@ -477,11 +454,19 @@ dependencies = [ dev = [ { name = "commitizen" }, { name = "commitlint" }, - { name = "hypothesis" }, + { name = "hatchling" }, + { name = "pandas-stubs" }, + { name = "pre-commit" }, + { name = "pyright" }, { name = "pytest" }, { name = "pytest-asyncio" }, { name = "pytest-cov" }, { name = "ruff" }, + { name = "scipy-stubs" }, + { name = "types-aiofiles" }, +] +gurobi = [ + { name = "gurobipy" }, ] interactive = [ { name = "ipython" }, @@ -490,10 +475,17 @@ interactive = [ [package.dev-dependencies] dev = [ + { name = "commitizen" }, + { name = "commitlint" }, { name = "como" }, { name = "pandas-stubs" }, { name = "pre-commit" }, + { name = "pytest" }, + { name = "pytest-asyncio" }, + { name = "pytest-cov" }, + { name = "ruff" }, { name = "scipy-stubs" }, + { name = "types-aiofiles" }, ] [package.metadata] @@ -502,40 +494,51 @@ requires-dist = [ { name = "anndata", specifier = ">=0.12.0" }, { name = "cobamp", git = "https://github.com/JoshLoecker/cobamp?rev=master" }, { name = "cobra", git = "https://github.com/ripaul/cobrapy?rev=hopsy-backend" }, - { name = "commitizen", marker = "extra == 'dev'", specifier = ">=4.1.0" }, - { name = "commitlint", marker = "extra == 'dev'", specifier = ">=1.3.0" }, + { name = "commitizen", marker = "extra == 'dev'", specifier = ">=4.8.3" }, + { name = "commitlint", marker = "extra == 'dev'", specifier = ">=1.3.1" }, { name = "fast-bioservices", specifier = ">=0.3.9" }, - { name = "gurobipy", specifier = "<14" }, - { name = "hopsy", specifier = ">=1.6.1" }, - { name = "hypothesis", marker = "extra == 'dev'", specifier = ">=6.122.1" }, + { name = "gurobipy", marker = "extra == 'gurobi'", specifier = "<14" }, + { name = "hatchling", marker = "extra == 'dev'", specifier = ">=1.27.0" }, { name = "ipython", marker = "extra == 'interactive'", specifier = ">=8.0.0" }, { name = "jupyterlab", marker = "extra == 'interactive'", specifier = ">=4.3.2" }, - { name = "kaleido", specifier = ">=0.2.1" }, + { name = "kaleido", specifier = ">=1.0.0" }, { name = "loguru", specifier = ">=0.7.2" }, - { name = "numpy", specifier = ">2.0" }, + { name = "numpy", specifier = ">=2" }, { name = "openpyxl", specifier = ">=3.1.5" }, { name = "pandas", specifier = ">=1.3.5" }, - { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.3.3" }, - { name = "pytest-asyncio", marker = "extra == 'dev'", specifier = ">=0.24.0" }, - { name = "pytest-cov", marker = "extra == 'dev'", specifier = ">=6.0.0" }, - { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.8.0" }, + { name = "pandas-stubs", marker = "extra == 'dev'", specifier = ">=2.3.2.250827" }, + { name = "pre-commit", marker = "extra == 'dev'", specifier = ">=4.2.0" }, + { name = "pyright", marker = "extra == 'dev'", specifier = ">=1.1.405" }, + { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.4.1" }, + { name = "pytest-asyncio", marker = "extra == 'dev'", specifier = ">=1.1.0" }, + { name = "pytest-cov", marker = "extra == 'dev'", specifier = ">=6.2.1" }, + { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.12.11" }, { name = "scanpy", specifier = ">=1.10.4" }, { name = "scikit-learn", specifier = ">=1.5.2" }, { name = "scipy", specifier = ">=1.13.0" }, + { name = "scipy-stubs", marker = "extra == 'dev'", specifier = ">=1.16.1.1" }, { name = "seaborn", specifier = ">=0.13.2" }, { name = "setuptools", specifier = ">=78.1.1" }, { name = "statsmodels", marker = "python_full_version < '3.12'", specifier = ">=0.13.0" }, { name = "statsmodels", marker = "python_full_version >= '3.12'", specifier = ">=0.14.0" }, { name = "troppo", git = "https://github.com/JoshLoecker/troppo?rev=master" }, + { name = "types-aiofiles", marker = "extra == 'dev'", specifier = ">=24.1.0.20250822" }, ] -provides-extras = ["dev", "interactive"] +provides-extras = ["dev", "gurobi", "interactive"] [package.metadata.requires-dev] dev = [ + { name = "commitizen", specifier = ">=4.8.3" }, + { name = "commitlint", specifier = ">=1.3.1" }, { name = "como", editable = "." }, { name = "pandas-stubs", specifier = ">=2.3.2.250827" }, { name = "pre-commit", specifier = ">=4.2.0" }, + { name = "pytest", specifier = ">=8.4.1" }, + { name = "pytest-asyncio", specifier = ">=1.1.0" }, + { name = "pytest-cov", specifier = ">=6.2.1" }, + { name = "ruff", specifier = ">=0.12.11" }, { name = "scipy-stubs", specifier = ">=1.16.1.1" }, + { name = "types-aiofiles", specifier = ">=24.1.0.20250822" }, ] [[package]] @@ -945,19 +948,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, ] -[[package]] -name = "h5netcdf" -version = "1.6.4" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "h5py" }, - { name = "packaging" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/5a/a1/e3ca842fd0895fcfb21c754a18fd8cd7362d1625b3a93408c982c38f4ec1/h5netcdf-1.6.4.tar.gz", hash = "sha256:83db7e5eb9b822bed2c79050d6cf8f36ecbd1039f4252bd90fab200edcaaf67d", size = 65832, upload-time = "2025-08-05T06:26:56.707Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5b/f5/ac71e692aad076d50a0f5f073204346d5f5577daffd21bb4b72c485f8959/h5netcdf-1.6.4-py3-none-any.whl", hash = "sha256:e0018e6a918f2bef2a4aa7b470a952b8a0b5d16a5893d59bea56524cc6207fcf", size = 50683, upload-time = "2025-08-05T06:26:55.644Z" }, -] - [[package]] name = "h5py" version = "3.14.0" @@ -985,43 +975,30 @@ wheels = [ ] [[package]] -name = "hishel" -version = "0.1.3" +name = "hatchling" +version = "1.27.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "httpx" }, + { name = "packaging" }, + { name = "pathspec" }, + { name = "pluggy" }, + { name = "trove-classifiers" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3e/b5/c063cd3eab8154ddd61deb07b50497cf24010727eaeec4d78ed1a6262986/hishel-0.1.3.tar.gz", hash = "sha256:db3e07429cb739dcda851ff9b35b0f3e7589e21b90ee167df54336ac608b6ec3", size = 36649, upload-time = "2025-07-06T14:19:23.528Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8f/8a/cc1debe3514da292094f1c3a700e4ca25442489731ef7c0814358816bb03/hatchling-1.27.0.tar.gz", hash = "sha256:971c296d9819abb3811112fc52c7a9751c8d381898f36533bb16f9791e941fd6", size = 54983, upload-time = "2024-12-15T17:08:11.894Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/29/a5/bf3553b44a36e1c5d2aa0cd15478e02b466dcaecdc2983b07068999d2675/hishel-0.1.3-py3-none-any.whl", hash = "sha256:bae3ba9970ffc56f90014aea2b3019158fb0a5b0b635a56f414ba6b96651966e", size = 42518, upload-time = "2025-07-06T14:19:22.336Z" }, + { url = "https://files.pythonhosted.org/packages/08/e7/ae38d7a6dfba0533684e0b2136817d667588ae3ec984c1a4e5df5eb88482/hatchling-1.27.0-py3-none-any.whl", hash = "sha256:d3a2f3567c4f926ea39849cdf924c7e99e6686c9c8e288ae1037c8fa2a5d937b", size = 75794, upload-time = "2024-12-15T17:08:10.364Z" }, ] [[package]] -name = "hopsy" -version = "1.6.1" +name = "hishel" +version = "0.1.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "arviz" }, - { name = "matplotlib" }, - { name = "numpy" }, - { name = "optlang" }, - { name = "pandas" }, - { name = "polyround" }, - { name = "scikit-learn" }, - { name = "scipy" }, - { name = "tqdm" }, + { name = "httpx" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a0/51/164517fc870771d17b3dd9d0afef23b128dc22352688069e238916dec309/hopsy-1.6.1.tar.gz", hash = "sha256:1eb812a0ad42c34ef4c4e949ad804b4860f18795c9447954e175bcbd4b1edf64", size = 7258188, upload-time = "2025-03-30T22:00:24.918Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3e/b5/c063cd3eab8154ddd61deb07b50497cf24010727eaeec4d78ed1a6262986/hishel-0.1.3.tar.gz", hash = "sha256:db3e07429cb739dcda851ff9b35b0f3e7589e21b90ee167df54336ac608b6ec3", size = 36649, upload-time = "2025-07-06T14:19:23.528Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7f/9e/5a8ff4b789477fe38d745a737505a181015366e1bed39d4fae037cd4daf3/hopsy-1.6.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:0ab345af6d585111a45905357f06ada13dc30a70599a23925b896cec9ed9048a", size = 729960, upload-time = "2025-03-30T21:59:44.756Z" }, - { url = "https://files.pythonhosted.org/packages/be/4b/1ff628b101104c61d600e8701a20a593721f810a517ac5b95de6a79b95c8/hopsy-1.6.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b8fc6257a71ebd06d1a967cae41151d2b31fe490bd3e8c246db14ae7549820a", size = 989378, upload-time = "2025-03-30T21:59:49.087Z" }, - { url = "https://files.pythonhosted.org/packages/04/2b/8f2cf2cc1cb4891c8ddaa5dbb7420809bf0674b82b3bc63fcf1f662880af/hopsy-1.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:20dfc5020a18fde834c38661edb8ea3f1b9c4245f282d79619afe798e0620336", size = 944853, upload-time = "2025-03-30T21:59:52.518Z" }, - { url = "https://files.pythonhosted.org/packages/e5/86/f94eb3f6a5f88e37e53ab45be32240a569ade754d7051003448bc4278e99/hopsy-1.6.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:84d6efa0202dcd7aab716fe240525f32482e90f1d7b8eea07b29d25254b4fc2e", size = 736022, upload-time = "2025-03-30T21:59:55.335Z" }, - { url = "https://files.pythonhosted.org/packages/c2/ae/51077c9eb7aeb51e2f3d6e16fea6930931ad55e73692d19c1da83870f30e/hopsy-1.6.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42843d9fc38d99df1861bc0965a87ecc57c52b11cf4dd1d224b4c9bc8f095eba", size = 992344, upload-time = "2025-03-30T21:59:58.038Z" }, - { url = "https://files.pythonhosted.org/packages/51/f8/612cfaaa6943e27257a22baeb5351c30dc96f0cc8c717457866ef377aba6/hopsy-1.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:efed7a7ec3e58e40055eb70d4694a59ca117ee04930528a8b95824d2f02371f3", size = 961936, upload-time = "2025-03-30T22:00:01.718Z" }, - { url = "https://files.pythonhosted.org/packages/fe/cd/b99bee05141201d7a280b2da0902f59dfda0ba7c96bb34fd53ed7ef3f955/hopsy-1.6.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:2675e0dba93591d5ff144b5d573d1867f09eac71e6c596f59d09390ab068b587", size = 736084, upload-time = "2025-03-30T22:00:04.393Z" }, - { url = "https://files.pythonhosted.org/packages/ca/21/537996d2328368323f08ac9d02fa2e158df63acc210bf19a2dd7ffa28bb5/hopsy-1.6.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdfb78fc445f0f70a2d7025ac42e02de34d2eac457892fd2cdd1f91826fdcece", size = 991801, upload-time = "2025-03-30T22:00:06.882Z" }, - { url = "https://files.pythonhosted.org/packages/1e/37/751ab1e34c8e900737e9d964f63a4dd7e1502684c98c7ef8b1875d24703e/hopsy-1.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:53d49094e96edd7e6b425c62006eae9aeb878fb41ae63cedc54639f685a62f69", size = 961795, upload-time = "2025-03-30T22:00:09.85Z" }, + { url = "https://files.pythonhosted.org/packages/29/a5/bf3553b44a36e1c5d2aa0cd15478e02b466dcaecdc2983b07068999d2675/hishel-0.1.3-py3-none-any.whl", hash = "sha256:bae3ba9970ffc56f90014aea2b3019158fb0a5b0b635a56f414ba6b96651966e", size = 42518, upload-time = "2025-07-06T14:19:22.336Z" }, ] [[package]] @@ -1052,19 +1029,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, ] -[[package]] -name = "hypothesis" -version = "6.138.13" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "attrs" }, - { name = "sortedcontainers" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/37/42/9cd666af7fd2c3e604f055f756e80d537faba5327cc72cbd44177792d074/hypothesis-6.138.13.tar.gz", hash = "sha256:2bea91629b8b3bb103a5b51442b1037cede3aae26e56ec063c52b9d5d8eaf70b", size = 466041, upload-time = "2025-09-01T14:02:51.468Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cc/82/823c202c8b349ff31a0718e46ff98074bebfb3aa20813091cea07821c25f/hypothesis-6.138.13-py3-none-any.whl", hash = "sha256:09f1130deb08e5d12fb3b59b55c113fd79debaaab9b224ffac17be8341de4326", size = 533564, upload-time = "2025-09-01T14:02:48.15Z" }, -] - [[package]] name = "identify" version = "2.6.13" @@ -2172,6 +2136,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/11/0a/daece46e65c821d153746566a1604ac90338f0279b1fb858a3617eb60472/pathos-0.3.4-py3-none-any.whl", hash = "sha256:fe44883448c05c80d518b61df491b496f6190bb6860253f3254d8c9afb53c340", size = 82261, upload-time = "2025-04-17T03:37:06.936Z" }, ] +[[package]] +name = "pathspec" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, +] + [[package]] name = "patsy" version = "1.0.1" @@ -2276,21 +2249,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] -[[package]] -name = "polyround" -version = "0.4.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "numpy" }, - { name = "optlang" }, - { name = "pandas" }, - { name = "scipy" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/4a/56/5b05ab0cbfe77dcf792e82ce1e1311461776c5413a99342f141641d7804a/polyround-0.4.0.tar.gz", hash = "sha256:e7312f0a8c435827627ac05d873969168f31373e5136f75e66c5a4d9e06f8833", size = 38570, upload-time = "2025-08-12T14:09:18.38Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/f1/9b10002d4114a08a807ce69cc1136eea62e32cbc9da2a24a12357c3201b7/polyround-0.4.0-py3-none-any.whl", hash = "sha256:4ac6a2a4b31f5ac83b32ee95e276fb6ec31a76ec0719d80ba4160c3f6bfa9cd3", size = 43357, upload-time = "2025-08-12T14:09:17.434Z" }, -] - [[package]] name = "pox" version = "0.3.6" @@ -2502,6 +2460,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/05/e7/df2285f3d08fee213f2d041540fa4fc9ca6c2d44cf36d3a035bf2a8d2bcc/pyparsing-3.2.3-py3-none-any.whl", hash = "sha256:a749938e02d6fd0b59b356ca504a24982314bb090c383e3cf201c95ef7e2bfcf", size = 111120, upload-time = "2025-03-25T05:01:24.908Z" }, ] +[[package]] +name = "pyright" +version = "1.1.405" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nodeenv" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fb/6c/ba4bbee22e76af700ea593a1d8701e3225080956753bee9750dcc25e2649/pyright-1.1.405.tar.gz", hash = "sha256:5c2a30e1037af27eb463a1cc0b9f6d65fec48478ccf092c1ac28385a15c55763", size = 4068319, upload-time = "2025-09-04T03:37:06.776Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d5/1a/524f832e1ff1962a22a1accc775ca7b143ba2e9f5924bb6749dce566784a/pyright-1.1.405-py3-none-any.whl", hash = "sha256:a2cb13700b5508ce8e5d4546034cb7ea4aedb60215c6c33f56cec7f53996035a", size = 5905038, upload-time = "2025-09-04T03:37:04.913Z" }, +] + [[package]] name = "pytest" version = "8.4.1" @@ -3179,15 +3150,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, ] -[[package]] -name = "sortedcontainers" -version = "2.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/c4/ba2f8066cceb6f23394729afe52f3bf7adec04bf9ed2c820b39e19299111/sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88", size = 30594, upload-time = "2021-05-16T22:03:42.897Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575, upload-time = "2021-05-16T22:03:41.177Z" }, -] - [[package]] name = "soupsieve" version = "2.8" @@ -3427,6 +3389,24 @@ dependencies = [ { name = "xlrd" }, ] +[[package]] +name = "trove-classifiers" +version = "2025.9.9.12" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/db/52/45fa9c4f39ada33d803e4c0f288e94dc2e9d499201a0aa5697e30ef8a0cb/trove_classifiers-2025.9.9.12.tar.gz", hash = "sha256:6a00942fc023f4f383af3254b4ed818d7fa7923a3c7c03b0e71da2ce71b538ab", size = 16970, upload-time = "2025-09-09T12:23:47.737Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/15/05/618f6a55cced5402364af0d7629cbfd04e9852d464193bde9bd03c85b56a/trove_classifiers-2025.9.9.12-py3-none-any.whl", hash = "sha256:d449bd9d4715105657732d6dd1f46aa1595278d01ef1716ca164b35867135a4f", size = 14136, upload-time = "2025-09-09T12:23:46.314Z" }, +] + +[[package]] +name = "types-aiofiles" +version = "24.1.0.20250822" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/19/48/c64471adac9206cc844afb33ed311ac5a65d2f59df3d861e0f2d0cad7414/types_aiofiles-24.1.0.20250822.tar.gz", hash = "sha256:9ab90d8e0c307fe97a7cf09338301e3f01a163e39f3b529ace82466355c84a7b", size = 14484, upload-time = "2025-08-22T03:02:23.039Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bc/8e/5e6d2215e1d8f7c2a94c6e9d0059ae8109ce0f5681956d11bb0a228cef04/types_aiofiles-24.1.0.20250822-py3-none-any.whl", hash = "sha256:0ec8f8909e1a85a5a79aed0573af7901f53120dd2a29771dd0b3ef48e12328b0", size = 14322, upload-time = "2025-08-22T03:02:21.918Z" }, +] + [[package]] name = "types-python-dateutil" version = "2.9.0.20250822" @@ -3569,34 +3549,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e1/07/c6fe3ad3e685340704d314d765b7912993bcb8dc198f0e7a89382d37974b/win32_setctime-1.2.0-py3-none-any.whl", hash = "sha256:95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390", size = 4083, upload-time = "2024-12-07T15:28:26.465Z" }, ] -[[package]] -name = "xarray" -version = "2025.8.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "numpy" }, - { name = "packaging" }, - { name = "pandas" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/d2/55/18055bc943029d25fb8f260b7e3b1485c30646ccf503a5e4a744d31a3b78/xarray-2025.8.0.tar.gz", hash = "sha256:323d4169ce72d4ef849de2b0bd122f9cd2905b82c7558169930dc16070982bab", size = 3034425, upload-time = "2025-08-14T16:52:13.872Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e6/c8/0f8db9d9478de8d70cbcae2056588401e26168e269d6d9919bf2ecb01f78/xarray-2025.8.0-py3-none-any.whl", hash = "sha256:1c454f32b38c93df68e450238c9473fe21248b8572d42ddd58c5170bb30934ee", size = 1342279, upload-time = "2025-08-14T16:52:10.956Z" }, -] - -[[package]] -name = "xarray-einstats" -version = "0.9.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "numpy" }, - { name = "scipy" }, - { name = "xarray" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/f1/10/ef474494a7f2102ec4c02352c723fa282c6237b600565eb82ee354291211/xarray_einstats-0.9.1.tar.gz", hash = "sha256:39b373deed43592c41d3fbf8863af62e19e01c1ae553ae5ff059a8df78d995c6", size = 33327, upload-time = "2025-06-18T15:53:28.499Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/17/8b/ed2f0f49385c3d7739cd4699954add26e8f09a372a0c3f04f2bde32fcea2/xarray_einstats-0.9.1-py3-none-any.whl", hash = "sha256:777339524e85d066f2ef9ed1e3a3fb63aead4c1065fd1406f30dfa4de58ce063", size = 39043, upload-time = "2025-06-18T15:53:24.088Z" }, -] - [[package]] name = "xlrd" version = "2.0.2" From 700489b112414b2e0f69391891a70d061e760603 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Thu, 18 Sep 2025 10:04:11 -0500 Subject: [PATCH 242/265] feat: added Kolmogorov-Smirnoff tests Signed-off-by: Josh Loecker --- main/como/stats/_two_sample.py | 60 +++++++++++++++++++ main/como/stats/ks_test.py | 102 +++++++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+) create mode 100644 main/como/stats/_two_sample.py create mode 100644 main/como/stats/ks_test.py diff --git a/main/como/stats/_two_sample.py b/main/como/stats/_two_sample.py new file mode 100644 index 00000000..d856ebeb --- /dev/null +++ b/main/como/stats/_two_sample.py @@ -0,0 +1,60 @@ +from abc import ABC, abstractmethod +from collections.abc import Mapping +from concurrent.futures import ProcessPoolExecutor, as_completed +from typing import ClassVar, Generic, Literal, TypeVar + +import numpy as np +import numpy.typing as npt +import pandas as pd + +T_BASE_SAMPLE = TypeVar("T_BASE_SAMPLE", bound="BaseTwoSample") +T_ALTERNATIVE = Literal["greater", "less", "two-sided"] +KS_RESULT = tuple[np.floating, np.floating, np.floating, np.int8] +MW_RESULT = tuple[np.floating, np.floating] +TEST_RESULT = TypeVar("TEST_RESULT", KS_RESULT, MW_RESULT) + +__all__ = ["BaseTwoSample"] + + +class BaseTwoSample(ABC, Generic[TEST_RESULT]): + _fields: ClassVar[dict[str, type]] + + @staticmethod + @abstractmethod + def _worker(a: npt.NDArray[np.floating], b: npt.NDArray[np.floating], **kwargs) -> TEST_RESULT: ... + + @property + @abstractmethod + def df(self) -> pd.DataFrame: + """DataFrame representation of the results. + + Returns: + A DataFrame with columns corresponding to the fields in `_fields`. + """ + ... + + @classmethod + def _run( + cls: type[T_BASE_SAMPLE], + df1: pd.DataFrame, + df2: pd.DataFrame, + cores: int = 1, + worker_kwargs: dict | None = None, + ) -> tuple[list[str], Mapping[str, npt.NDArray[np.float64 | np.uint8]]]: + all_reactions = list(set(df1.columns) & set(df2.columns)) + array_a = df1[all_reactions].to_numpy(dtype=np.float64, copy=False) + array_b = df2[all_reactions].to_numpy(dtype=np.float64, copy=False) + n = len(all_reactions) + + results = {field: np.empty(n, dtype=np.dtype(dtype)) for field, dtype in cls._fields.items()} + + with ProcessPoolExecutor(max_workers=cores) as pool: + futures = {pool.submit(cls._worker, array_a[:, i], array_b[:, i], **(worker_kwargs or {})): i for i in range(n)} + for future in as_completed(futures): + col_idx: int = futures[future] + res: KS_RESULT | MW_RESULT = future.result() + + for (field, _), value in zip(cls._fields.items(), res, strict=True): + results[field][col_idx] = value + + return all_reactions, results diff --git a/main/como/stats/ks_test.py b/main/como/stats/ks_test.py new file mode 100644 index 00000000..9f3c1778 --- /dev/null +++ b/main/como/stats/ks_test.py @@ -0,0 +1,102 @@ +from dataclasses import dataclass +from typing import ClassVar, Literal + +import numpy as np +import numpy.typing as npt +import pandas as pd +from scipy.stats import ks_2samp + +from como.stats._two_sample import KS_RESULT, T_ALTERNATIVE, BaseTwoSample + +__all__ = ["KSTest"] + + +@dataclass(frozen=True, kw_only=True, slots=True) +class KSTest(BaseTwoSample[KS_RESULT]): + _fields: ClassVar[dict[str, type]] = { + "statistic": np.float64, + "pvalue": np.float64, + "statistic_location": np.float64, + "statistic_sign": np.uint8, + } + + reaction_ids: list[str] + statistic: npt.NDArray[np.float64] + pvalue: npt.NDArray[np.float64] + statistic_location: npt.NDArray[np.float64] + statistic_sign: npt.NDArray[np.int8] + + @staticmethod + def _worker(a: npt.NDArray[np.floating], b: npt.NDArray[np.floating], **kwargs) -> KS_RESULT: + """Calculate the KS statistic. + + Args: + a: First array + b: Second array + kwargs: Additional keyword arguments to pass to `ks_2samp` + + Returns: + A tuple of (statistic, pvalue, statistic_location, statistic_sign) + """ + res = ks_2samp(a, b, **kwargs) + return res.statistic, res.pvalue, res.statistic_location, res.statistic_sign + + @classmethod + def run( + cls, + df1: pd.DataFrame, + df2: pd.DataFrame, + alternative: T_ALTERNATIVE = "two-sided", + method: Literal["auto", "exact", "asymp"] = "auto", + axis: int = 0, + nan_policy: Literal["raise", "propagate", "omit"] = "propagate", + keepdims: bool = False, + cores: int = 1, + ) -> "KSTest": + """Run the KS test on two dataframes. + + Args: + df1: The first dataframe to process; obtained from running `cobra.sampling.sample`. + Columns should be reaction IDs and rows should be samples. + df2: The second dataframe to process; obtained from running `cobra.sampling.sample`. + Columns should be reaction IDs and rows should be samples. + alternative: The alternative hypothesis to test. + method: The method to use for calculating the p-value. + axis: The axis to perform the test along. + nan_policy: The policy to use for handling NaNs. + keepdims: Whether to keep the dimensions of the input arrays. + cores: The number of CPU cores to use for multiprocessing. + + Returns: + An instance of `KSTest` containing the results of the test. + """ + all_reactions, results = cls._run( + df1=df1, + df2=df2, + cores=cores, + worker_kwargs={"alternative": alternative, "method": method, "axis": axis, "nan_policy": nan_policy, "keepdims": keepdims}, + ) + return cls( + reaction_ids=all_reactions, + statistic=results["statistic"].astype(np.float64), + pvalue=results["pvalue"].astype(np.float64), + statistic_location=results["statistic_location"].astype(np.float64), + statistic_sign=results["statistic_sign"].astype(np.int8), + ) + + @property + def df(self) -> pd.DataFrame: + """DataFrame representation of the results. + + Returns: + A DataFrame with columns "statistic", "pvalue", "statistic_location", and "statistic_sign". + """ + return pd.DataFrame( + { + "statistic": self.statistic, + "pvalue": self.pvalue, + "statistic_location": self.statistic_location, + "statistic_sign": self.statistic_sign, + }, + index=pd.Index(name="reaction_id", data=self.reaction_ids), + ) From eafaa9fcf5405f97253068d89bb4e91f05668155 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Thu, 18 Sep 2025 10:04:21 -0500 Subject: [PATCH 243/265] feat: added Mann-Whitney U-tests Signed-off-by: Josh Loecker --- main/como/stats/mann_whitney_test.py | 82 ++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 main/como/stats/mann_whitney_test.py diff --git a/main/como/stats/mann_whitney_test.py b/main/como/stats/mann_whitney_test.py new file mode 100644 index 00000000..98c8131d --- /dev/null +++ b/main/como/stats/mann_whitney_test.py @@ -0,0 +1,82 @@ +from dataclasses import dataclass +from typing import ClassVar, Literal + +import numpy as np +import numpy.typing as npt +import pandas as pd +from scipy.stats import PermutationMethod, mannwhitneyu + +from como.stats._two_sample import MW_RESULT, T_ALTERNATIVE, BaseTwoSample + +__all__ = ["MannWhitneyUTest"] + + +@dataclass(frozen=True, kw_only=True, slots=True) +class MannWhitneyUTest(BaseTwoSample[MW_RESULT]): + _fields: ClassVar[dict[str, type]] = {"statistic": np.float64, "pvalue": np.float64} + + reaction_ids: list[str] + statistic: npt.NDArray[np.float64] + pvalue: npt.NDArray[np.float64] + + @staticmethod + def _worker(a: npt.NDArray[np.floating], b: npt.NDArray[np.floating], **kwargs) -> MW_RESULT: + """Calculate the MWU statistic. + + Args: + a: First array + b: Second array + kwargs: Additional keyword arguments to pass to `mannwhitneyu` + + Returns: + A tuple of (statistic, pvalue) + """ + res = mannwhitneyu(x=a, y=b, **kwargs) + return np.float64(res.statistic), np.float64(res.pvalue) + + @classmethod + def run( + cls, + df1: pd.DataFrame, + df2: pd.DataFrame, + alternative: T_ALTERNATIVE = "two-sided", + use_continuity: bool = True, + axis: int = 0, + method: Literal["auto", "asymptotic", "exact"] | PermutationMethod = "auto", + cores: int = 1, + ) -> "MannWhitneyUTest": + """Run the MWU test on two dataframes. + + Args: + df1: The first dataframe to process; obtained from running `cobra.sampling.sample`. + Columns should be reaction IDs and rows should be samples. + df2: The second dataframe to process; obtained from running `cobra.sampling.sample`. + Columns should be reaction IDs and rows should be samples. + alternative: The alternative hypothesis to test. + use_continuity: Whether to apply a continuity correction when using the asymptotic method. + axis: The axis to perform the test along. + method: The method to use for calculating the p-value. + cores: The number of CPU cores to use for multiprocessing. + + Returns: + An instance of `MannWhitneyUTest` containing the results of the test. + """ + all_reactions, results = cls._run( + df1=df1, + df2=df2, + cores=cores, + worker_kwargs={"alternative": alternative, "use_continuity": use_continuity, "axis": axis, "method": method}, + ) + return cls(reaction_ids=all_reactions, statistic=results["statistic"].astype(np.float64), pvalue=results["pvalue"].astype(np.float64)) + + @property + def df(self) -> pd.DataFrame: + """DataFrame representation of the results. + + Returns: + A DataFrame with columns "statistic" and "pvalue". + """ + return pd.DataFrame( + {"statistic": self.statistic, "pvalue": self.pvalue}, + index=pd.Index(name="reaction_id", data=self.reaction_ids), + ) From 315d5c62fff1e920740d41e347fbb04d62284618 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Thu, 18 Sep 2025 10:04:30 -0500 Subject: [PATCH 244/265] feat: added Fisher Exact tests Signed-off-by: Josh Loecker --- main/como/stats/__init__.py | 0 main/como/stats/fisher_exact_test.py | 101 +++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 main/como/stats/__init__.py create mode 100644 main/como/stats/fisher_exact_test.py diff --git a/main/como/stats/__init__.py b/main/como/stats/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/main/como/stats/fisher_exact_test.py b/main/como/stats/fisher_exact_test.py new file mode 100644 index 00000000..068eb4c2 --- /dev/null +++ b/main/como/stats/fisher_exact_test.py @@ -0,0 +1,101 @@ +from dataclasses import dataclass +from typing import Annotated, Literal + +import cobra +import numpy as np +import scipy + + +@dataclass(frozen=True, kw_only=True, slots=True) +class FisherExactTest: + """Evalute Fisher's Exact Test for reaction presence. + + Fisher's Exact Test is a non-parametric statistical test used to determine if there are nonrandom associations between two variables. + It is useful in metabolic modeling because it can help assess whether the presence or absence of certain reactions in a metabolic model + is independent of a specific condition or treatment without assuming the distribution of the data. + + To calculate the Fisher's Exact Test, execute :func:`FisherExactTest.run`, which will return an instance of :class:`FisherExactTest` + + References: + [SciPy](https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.fisher_exact.html) + [Wikipedia](https://en.wikipedia.org/wiki/Fisher%27s_exact_test) + """ + + pathway: Annotated[str, "The pathway test"] + statistic: Annotated[float, "The odds ratio of the test"] + pvalue: Annotated[float, "The p-value of the test"] + a: Annotated[int, "Number of reactions in the pathway AND scenario model"] + b: Annotated[int, "Number of reactions in the pathway but NOT the scenario model"] + c: Annotated[int, "Number of reactions NOT in the pathway but ARE in the scenario model"] + d: Annotated[int, "Number of reactions NOT in the pathway NOR the scenario model"] + + @classmethod + def run( + cls: type["FisherExactTest"], + reference: cobra.Model, + scenario: cobra.Model, + pathway: str, + alternative: Literal["two-sided", "less", "greater"] = "two-sided", + ) -> "FisherExactTest": + """Perform a Fisher's Exact Test on two models with a known reference model. + + This test is based on the following assumptions: + - The general "reference" model was used to reconstruct the comprehensive and scenario models (such as Recon3D) + - A scenario-specific model exists that may not be representative of true biology + + --- + + Given the following contingency table for a set of conditions and N reactions: + - A: Reactions in `pathway` and the scenario-specific model + - B: Reactions in `pathway` but not the scenario-specific model + - C: Reactions in the scenario-specific model that are not a part of `pathway` + - D: Reactions not in `pathway` that are also not found in the scenario-specific model + + | Reaction Status | In scenario-specific model | Not in scenario-specific model | Row Total | + |:----------------:|:--------------------------:|:------------------------------:|:----------------------------:| + | In `pathway` | A | B | A + B | + | Not in `pathway` | C | D | C + D | + | Column Total | A + C | B + D | A + B + C + D (=N reactions) | + + A two-sided Fisher's exact test will ask the question: + > Is the inclusion or exclusion of this reaction in the patient model independent of its status in the reference model? + + If the scenario-specific dataset is "small", the reconstruction will likely have excluded/dropped some reactions + as a result of the limited data available. This means the Fisher's exact test may show **many apparent differences**. + However, this could be noise from undersampling and not indicative of the true underlying biology. + In practice, if only a few reactions fall into "condition A" (above), this suggests that the scenario-specific model is too sparse + and not reconstructed with enough data. + + Args: + reference: The general reference model that was used to build the model (e.g., Recon3D) + scenario: The scenario-specific model to test (e.g., built using a small cohort of single-cell RNA-seq data) + pathway: The pathway to investigate for a Fisher's Exact Test + alternative: The alternative hypothesis to test + + Returns: + The p-value indicating whether the reaction presence in the scenario model is independent of the reference model. + """ + scenario_rxn_ids: set[str] = {rxn.id for rxn in scenario.reactions} + + a = 0 # a reaction is in the given pathway and scenario model + b = 0 # a reaction is in the given pathway but not the scenario model + c = 0 # a reaction is not in the given pathway but is in the scenario model + d = 0 # a reaction is not in the given pathway OR the scenario model + + for rxn in reference.reactions: + in_pathway = rxn.subsystem == pathway + in_scenario = rxn.id in scenario_rxn_ids + + if in_pathway: + if in_scenario: + a += 1 + else: + b += 1 + else: + if in_scenario: + c += 1 + else: + d += 1 + + result = scipy.stats.fisher_exact(np.array([[a, b], [c, d]]), alternative=alternative) + return cls(statistic=result.statistic, pvalue=result.pvalue, pathway=pathway, a=a, b=b, c=c, d=d) From 16d5c834aa8f04831ee9e356556e2853193a3baa Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Thu, 18 Sep 2025 10:04:53 -0500 Subject: [PATCH 245/265] feat: added unit tests for KS statistics Signed-off-by: Josh Loecker --- tests/inputs/expected_ks_results.csv | 11 ++++++++ tests/unit/test_ks_stats.py | 39 ++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 tests/inputs/expected_ks_results.csv create mode 100644 tests/unit/test_ks_stats.py diff --git a/tests/inputs/expected_ks_results.csv b/tests/inputs/expected_ks_results.csv new file mode 100644 index 00000000..b6640caf --- /dev/null +++ b/tests/inputs/expected_ks_results.csv @@ -0,0 +1,11 @@ +reaction_id,statistic,pvalue,statistic_location,statistic_sign +0,0.395,4.9525690933187676e-70,0.4804374873638153,1 +1,0.382,2.100275595200399e-65,0.6599260568618774,1 +2,0.416,7.105707649012374e-78,0.5388635396957397,1 +3,0.388,1.614348883239596e-67,0.460053950548172,1 +4,0.368,1.2990993761208528e-60,0.383552223443985,1 +5,0.382,2.100275595200399e-65,0.5969201326370239,1 +6,0.399,1.7223838690805776e-71,0.4544350504875183,1 +7,0.401,3.166572974357379e-72,0.5225677490234375,1 +8,0.385,1.8608981050282822e-66,0.6594884991645813,1 +9,0.355,2.435056842111727e-56,0.5130801200866699,1 diff --git a/tests/unit/test_ks_stats.py b/tests/unit/test_ks_stats.py new file mode 100644 index 00000000..08403d46 --- /dev/null +++ b/tests/unit/test_ks_stats.py @@ -0,0 +1,39 @@ +import numpy as np +import pandas as pd +import pytest +from como.stats.ks_test import KSTest + + +@pytest.fixture +def expected_result() -> pd.DataFrame: + df = pd.read_csv("tests/inputs/expected_ks_results.csv", index_col=0) + df["statistic_sign"] = df["statistic_sign"].astype(np.int8) + return df + + +@pytest.mark.parametrize("cores", [1, 2, 4]) +def test_ks_stats(expected_result: pd.DataFrame, cores: int): + seed = 123456789 + size = 1_000 + cols = 10 + gen = np.random.Generator(np.random.PCG64DXSM(seed=seed)) + + df1 = pd.DataFrame( + index=list(range(size)), + columns=list(range(cols)), + data=gen.normal(loc=0, size=size * cols).reshape(size, cols).astype(np.float32), + ) + df2 = pd.DataFrame( + index=list(range(size)), + columns=list(range(cols)), + data=gen.normal(loc=1, size=size * cols).reshape(size, cols).astype(np.float32), + ) + + real_result = KSTest.run(df1, df2, cores=cores) + real_df = real_result.df + # real_df.to_csv("/Users/joshl/Projects/COMO/tests/inputs/expected_ks_results.csv") + # assert False + assert len(expected_result.columns) == len(real_df.columns) + assert len(expected_result) == len(real_df) + assert all(col in real_df.columns for col in expected_result.columns) + pd.testing.assert_frame_equal(expected_result, real_df) From ae1ca0466dab730161b6372d48dbd817431563fd Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Thu, 18 Sep 2025 10:05:01 -0500 Subject: [PATCH 246/265] feat: added unit tests for Mann Whitney statistics Signed-off-by: Josh Loecker --- tests/inputs/expected_mwu_results.csv | 11 ++++++++ tests/unit/test_mwu_stats.py | 36 +++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 tests/inputs/expected_mwu_results.csv create mode 100644 tests/unit/test_mwu_stats.py diff --git a/tests/inputs/expected_mwu_results.csv b/tests/inputs/expected_mwu_results.csv new file mode 100644 index 00000000..2964651f --- /dev/null +++ b/tests/inputs/expected_mwu_results.csv @@ -0,0 +1,11 @@ +reaction_id,statistic,pvalue +0,246270.0,5.908986833278511e-86 +1,249044.0,3.9754187610805028e-84 +2,229206.0,1.2240591968361702e-97 +3,239091.0,8.876596072735212e-91 +4,251640.0,1.958199039053936e-82 +5,241101.0,2.051997493199763e-89 +6,234548.0,6.711468976164077e-94 +7,230278.0,6.983489755287457e-97 +8,239065.0,8.521868135307152e-91 +9,259912.0,3.698879057625339e-77 diff --git a/tests/unit/test_mwu_stats.py b/tests/unit/test_mwu_stats.py new file mode 100644 index 00000000..9b1823e4 --- /dev/null +++ b/tests/unit/test_mwu_stats.py @@ -0,0 +1,36 @@ +import numpy as np +import pandas as pd +import pytest +from como.stats.mann_whitney_test import MannWhitneyUTest + + +@pytest.fixture +def expected_result() -> pd.DataFrame: + df = pd.read_csv("tests/inputs/expected_mwu_results.csv", index_col=0) + return df + + +@pytest.mark.parametrize("cores", [1, 2, 4]) +def test_mannwhitney_stats(expected_result: pd.DataFrame, cores: int): + seed = 123456789 + size = 1_000 + cols = 10 + gen = np.random.Generator(np.random.PCG64DXSM(seed=seed)) + + df1 = pd.DataFrame( + index=list(range(size)), + columns=list(range(cols)), + data=gen.normal(loc=0, size=size * cols).reshape(size, cols).astype(np.float32), + ) + df2 = pd.DataFrame( + index=list(range(size)), + columns=list(range(cols)), + data=gen.normal(loc=1, size=size * cols).reshape(size, cols).astype(np.float32), + ) + + real_result = MannWhitneyUTest.run(df1, df2, cores=cores) + real_df = real_result.df + assert len(expected_result.columns) == len(real_df.columns) + assert len(expected_result) == len(real_df) + assert all(col in real_df.columns for col in expected_result.columns) + pd.testing.assert_frame_equal(expected_result, real_df) From d26bc77c699c620e4f2f5a2a8ad62efc6158ebbd Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Thu, 18 Sep 2025 16:00:54 -0500 Subject: [PATCH 247/265] feat: added unit tests for Fisher's Exact statistics Signed-off-by: Josh Loecker --- tests/inputs/naiveB_model.xml | 181471 +++++++++++++++++++++++++++++ tests/unit/test_fisher_stats.py | 16 + 2 files changed, 181487 insertions(+) create mode 100755 tests/inputs/naiveB_model.xml create mode 100644 tests/unit/test_fisher_stats.py diff --git a/tests/inputs/naiveB_model.xml b/tests/inputs/naiveB_model.xml new file mode 100755 index 00000000..4de8cf9a --- /dev/null +++ b/tests/inputs/naiveB_model.xml @@ -0,0 +1,181471 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Confidence Level: 0.0

+

NOTES: carrier-mediated transport - but which and how is unknown IT

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: mechanism is unknown IT

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD, IT

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT reaction involved in formation of 4-hydroxybenzoate from tyrosine.

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: We show in this study that the product of Slc6a18 called XT2 is a Na+- and Cl dependent neutral amino acid transporter and displays, compared with B0AT1, a lower K0.5 and a different substrate selectivity. Because of its broad transport selectivity for neutral amino acids, we suggest that it be renamed B0AT3. Exclusive to kidney, responsible for re-absorption of neutral amino acids (gly, ala, val, leu, ile, met, ser, cys, asn, gln, phe, tyr, trp, arg, glu).

+

Confidence Level: 0.0

+

NOTES: 4

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Used to make Ubiquinone-10 enzyme has not been identified yet. IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: PMID:486467 MM

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: as described in Bender (Nutritional biochmeistry of the vitamins, 2nd edition) MM

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM. activity measured in rat, 3-sulfinoalanine is substrate found in human brain

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM. activity measured in rat, 3-sulfinoalanine is substrate found in human brain

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: specific mechanism not known, proton dependence for trans-mit transport has been suggested, however directionality and stoichiometry has not yet been elucidated. see PMID: 12770731 and others NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: specific mechanism not known, proton dependence for trans-mit transport has been suggested, however directionality and stoichiometry has not yet been elucidated. see PMID: 12770731 and others NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD. Delta-aminolevulinic acid is produced in mitochondria then converted to PBG in the cytoplasm. Could not find anything on the transporter itself.

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: specific mechanism not known, proton dependence for trans-mit transport has been suggested, however directionality and stoichiometry has not yet been elucidated. see PMID: 12770731 and others NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: carrier-mediated transport - but which and how is unknown IT

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism. IT

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: carrier-mediated transport - but which and how is unknown IT

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism. IT

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC: 2.4.1.228 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: kh 1/6/03

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM. 2-Methyl-3-acetoacetyl-CoA excreted into urine for patients with disease deficiency

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD NJ - added peroxisomal version

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT, TDV changed name from "tm2" to "t2m" - NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV (9/14/2004)

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV-mitochondrial version JLR- also acts on propanoate AMF- made reaction to create AMP not ADP and changed EC

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: transport between cytosol and Golgi/ER presumed presumed facilitated transport, but unknown co-substrates, see PMID: 12739170, Hirabayashi et al NJ changed name from ACCOArt to ACCOAtr for consistency - NCD

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism for transport - however must get to other intracellular compartments (e.g. lysosome for degradation) NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism for transport - however must get to other intracellular compartments (e.g. lysosome for degradation) NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: ATP dependent citrate lyase. Reaction is reversible in KEGG (new EC 2.3.3.8) NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC-2.5.1.56 NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC-2.5.1.56 NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: H symport into lysososome. See PMID: 2768261 and PMID: 10581036 ( for human evidence). Sialic acid storage disorders (due to transporter mutations) require import and export e.g. PMID: 2768266 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Assume NAD/NADH as acceptors Lumped long-chain acyl-CoA dehydrogenase (EC 1.3.99.13) This reaction is therefore equilivalent to trans-2-enoyl-CoA reductase (NAD) (EC 1.3.1.44)

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IF. Biochemical

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: INVALID ECO TERM: IFH

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: AMF

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IF

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Added EC- JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: adenosine deaminase has been found on cell surface in human (Gonzales-Gronow et al, JBC, 2004,279,20993-20998). IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: most likely NOT physiological - detailed information about the peroxisomal transporters has not yet been achieved - this transport is most likely dependent on a concomitant energy consuming reaction (human ABC peroxisomal transporters: PEX family - check in future for new research articles describing biochemistry and stoichiometry) NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: interaction between peroxisomes and ER (some enzymes on the outer membrane) NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: FULLR corresponds to acyl/R groups in texts. NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC taken from Ligand TV. Genetic

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TV

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: tv Mendz pg. 201 Reversibility is unclear.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB based om PMID 10823827

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD. For NAD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: See also ALDH1 (1.2.1.3); r0177

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: cofactors + usage still not clear see version ALOX5b for ATP concomittant hydrolysis - literature notes in vitro requirement for Ca and ATP for activity in addition to Fe

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: cofactors + usage still not clear unknown mechanism - biochemistry supported by PMID: 2829172, 11160764

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Added by RS/TV (6/17/05)

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: "diffusion" NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: for MDR transport mechanism NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: specific mechanism not known, proton dependence for trans-mit transport has been suggested, however directionality and stoichiometry has not yet been elucidated. see PMID: 12770731 and others NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism, presumed diffusion NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: cytosolic conversion of pooled FA into palmitate (so subsequent transport into mit w/ FA oxidation can occur). Since Carbon stoichiometry normalized wrt C16 ratio between Rgroupcoa and pmtcoa is 1:1 HR fatty acid metabolism - R groups = acyl groups, Rtotal, Rtotal2, Rtotal3 correspond to three possible acyl groups added to glycerol R1 - C16 groups R2 - essential FA + associated derivatives R3 - non-essential, dietary FA (C18) R4 - monounsaturated FA R5 -other (C26, C24) NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: cytosolic conversion of pooled FA into palmitate (so subsequent transport into mit w/ FA oxidation can occur). Since Carbon stoichiometry normalized wrt C16 ratio between Rgroupcoa and pmtcoa is 1:1 HR fatty acid metabolism - R groups = acyl groups, Rtotal, Rtotal2, Rtotal3 correspond to three possible acyl groups added to glycerol R1 - C16 groups R2 - essential FA + associated derivatives R3 - non-essential, dietary FA (C18) R4 - monounsaturated FA R5 -other (C26, C24) NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB based om PMID 10823827

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: most likely NOT physiological - detailed information about the peroxisomal transporters has not yet been achieved - this transport is most likely dependent on a concomitant energy consuming reaction (human ABC peroxisomal transporters: PEX family - check in future for new research articles describing biochemistry and stoichiometry) NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT, TDV

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT, TDV

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism, however glucuronidated metabolites need to get out of the cell NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _01-25-05 based on Wang et al 1999, JBC, 274(21), 14875-14888. IT 03-07-05:replaced IT: now based on Balamurugan et al, 2005, Am J Physiol Renal Physiol, 288, F823-831,2005

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD ER version NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TV

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TV (see C160CRN)

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TV

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV C20:4 transport

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV C20:4 transport

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: interaction between peroxisomes and ER (some enzymes on the outer membrane) NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD ER version NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD ER version NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD ER - NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC 1.-.-.- NCD ER version NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: double check rxn specifics - see lit ref: Marijanovic, Molecular Endocrinology 2003 17:1715-1725 ER version NJ

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: double check rxn specifics - see lit ref: Marijanovic, Molecular Endocrinology 2003 17:1715-1725 ER version NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: plasma membrane version (SR and ER versions also exist) stoichiometry actually varies (number of Ca/ATP transported). See PMID: 7876199 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TV

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: See PMID: 11946414 NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: multiple EC EC 1.1.1.189 EC 1.1.1.197 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ - reversibility of enzyme found in lit by NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism, presumed diffusion NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: ER membrane - but on cytosolic surface NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: inner mitochondrial membrane NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: non-vesicular intracellular transport of ceramide

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: non-vesicular intracellular transport of ceramide

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: non-vesicular intracellular transport of glucocerebroside

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: non-vesicular intracellular transport of glucocerebroside

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism for transport - no strong evidence to indicate further lysosomal or golgi metabolism NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism for transport - no strong evidence to indicate further lysosomal or golgi metabolism NJ

+ +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Confidence Level: 0.0

+

NOTES: specific mechanism not known, proton dependence for trans-mit transport has been suggested, however directionality and stoichiometry has not yet been elucidated. see PMID: 12770731 and others NJ. NS: transport from lysozyme to mitochondria?

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: specific mechanism not known, proton dependence for trans-mit transport has been suggested, however directionality and stoichiometry has not yet been elucidated. see PMID: 12770731 and others NJ

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: specific mechanism not known, proton dependence for trans-mit transport has been suggested, however directionality and stoichiometry has not yet been elucidated. see PMID: 12770731 and others NJ

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: antiport with malate IF

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: antiport with PEP IF

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: kegg C02305 MJC SAB c

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: interaction between peroxisomes and ER (some enzymes on the outer membrane) NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IF

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: diffusion NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _2.1.1.114 IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _2.1.1.- IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _1.13.12.- IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _1.14.13.- IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: mechanism not currently elucidated NJ

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Note that this reaction occurs in the endosome during endocytosis, but has been compartmentalized as lysosomal. NCD

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Note that this reaction occurs in the endosome during endocytosis, but has been compartmentalized as lysosomal. NCD

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Note that this reaction occurs in the endosome during endocytosis, but has been compartmentalized as lysosomal. NCD

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Note that this reaction occurs in the endosome during endocytosis, but has been compartmentalized as lysosomal. NCD

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Note that this reaction occurs in the endosome during endocytosis, but has been compartmentalized as lysosomal. NCD

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IF old EC number (4.1.3.7) is obsolete -- transferred to 2.3.3.1 NCD. Biochemical

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: mm

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IF

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: reaction according to KEGG MM

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Merged CYSGLYexR and CYSGLYex - (May 2011) IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: adenosine deaminase has been found on cell surface in human (Gonzales-Gronow et al, JBC, 2004,279,20993-20998). IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT (2.7.1.74)

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT (2.7.1.74)

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT (2.7.1.74)

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: interaction between peroxisomes and ER (some enzymes on the outer membrane) NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT rxn is done by 4.1.2.14 and 4.1.3.16 mitochondrial isozyme - NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: ubiquinone precursor, transport by "diffusion" -> actually beleived to be flip-flop mechanism (PMID: 12840657). NJ

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: for homo sapiens, noted to actually be NADH-cyt b5, using NADH at present NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: for homo sapiens, noted to actually be NADH-cyt b5, using NADH at present NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: for homo sapiens, noted to actually be NADH-cyt b5, using NADH at present NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: FULLR corresponds to acyl/R groups in texts. NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Added EC- JLR IT

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: lanosterol -> cholesterol pathway FAD known to be cofactor, other details missing NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: lanosterol -> cholesterol pathway see paper refs Moebius et al PNAS 95:1899-1902 - check/re-check lit for more specific details (NADPH known to be cofactor - also NADH?, possibly rev?) NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: lanosterol -> cholesterol pathway see paper refs Moebius et al PNAS 95:1899-1902 - check/re-check lit for more specific details (NADPH known to be cofactor - also NADH?, possibly rev?) NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Used to make Ubiquinone-10 EC 2.1.1.114 IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD,IT

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _06-15-05 - EC 1.3.3.1 IT based on Bader et al, 1998, Prot. Expr. Purif 13,414-422 (I guess it is ubiquinone but i am not sure ) (needs FMN as cofactor) v(enzyme is located in inner-membrane of mitochondria, reaction take place in cytosol (Fig. 8 Rawls et al PMID: 10727948 )

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism for transport - however must get to other intracellular compartments (e.g. lysosome for degradation) NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+

NOTES: peroxisomal version - NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: dmhptcoa is 'special' because its biochemical fat isn't known NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: added EC num; also EC 5.4.2.4 -- NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: enzyme has not been identified yet IT

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: peroxisomal version - NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: by analogy to other dimethyl transferase rxns. See PMID: 10586494, human interemidate (from C15 ->C50) not explicitly determined yet, however it is known to occur since this pathway is essential in Q10 synthesis. For human metabolism: may be associated w/ GeneID: 23590 TPRT - recheck lit in future IT and NJ

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: CoA transfer not explicitly in rxn (accounted for in Rtotal rxn -> ARTF) NJ

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _01-26-05 IT based on Lu et al JBC,1992,24,17102-17109

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _01-26-05 IT based on Lu et al JBC,1992,24,17102-17109

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: involved in lanosterol -> cholesterol pathway NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: involved in lanosterol -> cholesterol pathway NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM. based on assigned short chain enoyl-CoA hydratase activity

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB for mito

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB for x

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM. based on assigned short chain enoyl-CoA hydratase activity

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD SAB oaa -> asp-L

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: specific mechanism not known, proton dependence for trans-mit transport has been suggested, however directionality and stoichiometry has not yet been elucidated. see PMID: 12770731 and others NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: specific mechanism not known, proton dependence for trans-mit transport has been suggested, however directionality and stoichiometry has not yet been elucidated. see PMID: 12770731 and others NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TV (5/4/05) Voet p.571

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TV Ruzicka F, JBC, 1977

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: AR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TV catalyzed by acyl-CoA synthetases

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: AR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TV catalyzed by acyl-CoA synthetases

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TV catalyzed by acyl-CoA synthetases

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ, RE1514C

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ, RE3114C

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: rev version so additional rxn doesn't need to be added to "unload" AA NJ. Merged GPR from FACOAL204 and FACOAL204i - (May 2011) IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: rev version so additional rxn doesn't need to be added to "unload" AA alternate to arachidonic acid (n-3 rather than n-6) NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: cytoplasmic version -NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: diffusion - but unidirectional uptake into ER (to avoid loops w/ NAD/NADP) NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: most likely NOT physiological - detailed information about the peroxisomal transporters has not yet been achieved - this transport is most likely dependent on a concomitant energy consuming reaction (human ABC peroxisomal transporters: PEX family - check in future for new research articles describing biochemistry and stoichiometry) NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: diffusion - but unidirectional output from ER (to avoid loops w/ NAD/NADP) NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: most likely NOT physiological - detailed information about the peroxisomal transporters has not yet been achieved - this transport is most likely dependent on a concomitant energy consuming reaction (human ABC peroxisomal transporters: PEX family - check in future for new research articles describing biochemistry and stoichiometry) NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: fatty acid elongation step NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: fatty acid elongation step NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: fatty acid elongation step NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: fatty acid elongation step NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: fatty acid omega hydroxylation NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TV Other enzymes: 1.3.3.6, 4.2.1.74, 4.2.1.17, 1.1.1.35, 1.1.1.211

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TV Other enzymes: 1.3.3.6, 4.2.1.74, 4.2.1.17, 1.1.1.35, 1.1.1.211

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _4 rounds of beta ox c16:0 -> c8:0, 4 step FAO lumped for 2 rounds also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _4 rounds of beta ox - in peroxisome, no fad, 1ste set of beta-ox is by acyl-coa oxidase (passes electrons directly to o2 -> h2o2) c16:0 -> c8:0, 4 step FAO lumped for 2 rounds also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _4 rounds of beta ox, 1 loss of degree of unsat -> only 3 fad oxidized c16:1 -> c8:0 4 step FAO lumped for 2 rounds also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _4 rounds of beta ox, 1 loss of degree of unsat -> only 3 fad oxidized c16:1 -> c8:0 4 step FAO lumped for 2 rounds also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TV Other enzymes: 1.3.3.6, 4.2.1.74, 4.2.1.17, 1.1.1.35, 1.1.1.211

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: - in peroxisome, no fad, 1ste set of beta-ox is by acyl-coa oxidase (passes electrons directly to o2 -> h2o2) NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _5 rounds of beta ox, 1 loss of degree of unsat -> 4 fad oxidized c18:1 -> c8:0 4 step FAO lumped for 2 rounds also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _5 rounds of beta ox, 1 loss of degree of unsat -> 4 fad oxidized c18:1 -> c8:0 4 step FAO lumped for 2 rounds also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _5 rounds of beta ox, 1 loss of degree of unsat -> 4 fad oxidized c18:1 -> c8:0 4 step FAO lumped for 2 rounds also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: c18:2,n-6 -> c8:0 - 5 rounds of beta ox, lose 2 degrees of unsat - only 3 fad oxidized 4 step FAO lumped also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: c18:2, transe -> c8:0 - 5 rounds of beta ox, lose 2 degrees of unsat - only 3 fad oxidized 4 step FAO lumped also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: c18:3, n-3 -> c8:0 - 5 rounds of beta ox, lose 3 degrees of unsat - only 2 fad oxidized 4 step FAO lumped also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _5 rounds of beta ox, 3 degrees loss of saturation -> only 2 fad oxidized to fadh2 - in peroxisome, no fad, 1ste set of beta-ox is by acyl-coa oxidase (passes electrons directly to o2 -> h2o2) peroxisomal (very long chain FA) c18:3,n-6 -> c8:0, 4 step FAO lumped for 2 rounds also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _5 rounds of beta ox, 3 degrees loss of saturation -> only 2 fad oxidized to fadh2 - in peroxisome, no fad, 1ste set of beta-ox is by acyl-coa oxidase (passes electrons directly to o2 -> h2o2) peroxisomal (very long chain FA) c18:3,n-6 -> c8:0, 4 step FAO lumped for 2 rounds also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _5 rounds of beta ox, 4 degrees loss of saturation -> only 1 fad oxidized to fadh2 peroxisomal (very long chain FA) c18:4,n-6 -> c8:0, 4 step FAO lumped for 2 rounds also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _5 rounds of beta ox, 4 degrees loss of saturation -> only 1 fad oxidized to fadh2 - in peroxisome, no fad, 1ste set of beta-ox is by acyl-coa oxidase (passes electrons directly to o2 -> h2o2) peroxisomal (very long chain FA) c18:4,n-6 -> c8:0, 4 step FAO lumped for 2 rounds also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: c20:0 -> c18:0 4 step FAO lumped also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: peroxisomal (very long chain FA) - in peroxisome, no fad, 1ste set of beta-ox is by acyl-coa oxidase (passes electrons directly to o2 -> h2o2) c20:0 -> c18:0 4 step FAO lumped also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: c20:3 -> c18:3 4 step FAO lumped also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TV Other enzymes: 1.3.3.6, 4.2.1.74, 4.2.1.17, 1.1.1.35, 1.1.1.211

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _1 rounds of beta ox c20:4 -> c18:4 4 step FAO lumped for 2 rounds also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _1 round beta ox, 1 degree loss of sat -> no fad oxidation peroxisomal (very long chain FA) c20:5,n-3 -> c18:4, n-3 - final '3' in abbreviation indicates omega3 FA 4 step FAO lumped for 2 rounds also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _1 round beta ox, 1 degree loss of sat -> no fad oxidation - in peroxisome, no fad, 1ste set of beta-ox is by acyl-coa oxidase (passes electrons directly to o2 -> h2o2) peroxisomal (very long chain FA) c20:5,n-3 -> c18:4, n-3 - final '3' in abbreviation indicates omega3 FA 4 step FAO lumped for 2 rounds also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _1 round beta ox peroxisomal (very long chain FA) c22:4,n-6 -> c20:4, n-6 - final '6' in abbreviation indicates omega6 FA 4 step FAO lumped for 2 rounds also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _1 round beta ox - in peroxisome, no fad, 1ste set of beta-ox is by acyl-coa oxidase (passes electrons directly to o2 -> h2o2) peroxisomal (very long chain FA) c22:4,n-6 -> c20:4, n-6 - final '6' in abbreviation indicates omega6 FA 4 step FAO lumped for 2 rounds also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _2 rounds of beta-ox, plus a loss of 2 degrees of desatuartion, so no fad is oxidized peroxisomal (very long chain FA) c22:5,n-6 -> c18:3, n-6 - final '6' in abbreviation indicates omega6 FA 4 step FAO lumped for 2 rounds also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _2 rounds of beta-ox, plus a loss of 2 degrees of desatuartion, so no fad is oxidized - in peroxisome, no fad, 1ste set of beta-ox is by acyl-coa oxidase (passes electrons directly to o2 -> h2o2) peroxisomal (very long chain FA) c22:5,n-6 -> c18:3, n-6 - final '6' in abbreviation indicates omega6 FA 4 step FAO lumped for 2 rounds also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _1 round beta ox - c22:5,n-3 -> c20:5, n-3 - final '3' in abbreviation indicates omega3 FA 4 step FAO lumped for 2 rounds also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _1 round beta ox - in peroxisome, no fad, 1ste set of beta-ox is by acyl-coa oxidase (passes electrons directly to o2 -> h2o2) peroxisomal (very long chain FA) c22:5,n-3 -> c20:5, n-3 - final '3' in abbreviation indicates omega3 FA 4 step FAO lumped for 2 rounds also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TV Other enzymes: 1.3.3.6, 4.2.1.74, 4.2.1.17, 1.1.1.35, 1.1.1.211

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _1 round of beta-oxidation, loses degree of desat, so no fad peroxisomal (very long chain FA) c22:6,n-3 -> c20:5, n-3 4 step FAO lumped also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _1 round of beta-oxidation, loses degree of desat, so no fad - in peroxisome, no fad, 1ste set of beta-ox is by acyl-coa oxidase (passes electrons directly to o2 -> h2o2) peroxisomal (very long chain FA) c22:6,n-3 -> c20:5, n-3 4 step FAO lumped also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: peroxisomal (very long chain FA) - in peroxisome, no fad, 1ste set of beta-ox is by acyl-coa oxidase (passes electrons directly to o2 -> h2o2) c24:0 -> c20:0 4 step FAO lumped for 2 rounds also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: peroxisomal (very long chain FA) - in peroxisome, no fad, 1ste set of beta-ox is by acyl-coa oxidase (passes electrons directly to o2 -> h2o2) c24:1 -> c18:1 - 3 rounds beta-ox 4 step FAO lumped also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: peroxisomal (very long chain FA) - in peroxisome, no fad, 1ste set of beta-ox is by acyl-coa oxidase (passes electrons directly to o2 -> h2o2) c26:0 -> c24:0 4 step FAO lumped also includes EC 1.1.1.35, 1.1.1.211, 1.3.3.6, 4.2.1.17, 4.2.1.74 -> into pmtcoa NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV (9/7/2004) Other enzymes: 1.3.3.6, 4.2.1.74, 4.2.1.17, 1.1.1.35, 1.1.1.211

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: electroneutral transport NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IF

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD; r0096

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD,IT

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: diffusion NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: cholesterol precursor, transport by "diffusion" -> actually beleived to be flip-flop mechanism (PMID: 12840657). See also Krisans (PMID: 14713247, PMID: 12121718) for synthesis of cholesterol pathway (why FRDP needs to be transported between ER and peroxisome) NJ

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: cholesterol precursor, transport by "diffusion" -> actually beleived to be flip-flop mechanism (PMID: 12840657). See also Krisans (PMID: 14713247, PMID: 12121718) for synthesis of cholesterol pathway (why FRDP needs to be transported between ER and peroxisome) NJ

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism, however these blood groups need to make it to the extracellular surface of cells NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IF. Biochemical

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Keratan sulfate II biosynthesis NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Keratan sulfate II biosynthesis NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Keratan sulfate II biosynthesis NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Keratan sulfate II biosynthesis NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Keratan sulfate II biosynthesis NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Keratan sulfate II biosynthesis NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Keratan sulfate II biosynthesis NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Keratan sulfate II biosynthesis NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: replaces old version which contains redundant metabolite (gly3p) NCD split compartmentation NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: spontaneous reaction NCD

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB m TDV: name change from G5SDm

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: tv, jp NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB c

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism for transport - however must get to other intracellular compartments (e.g. lysosome for degradation) NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism for transport - however must get to other intracellular compartments (e.g. lysosome for degradation) NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism for transport - not known if it is energy dependent or not, recycling and IC transport is important to get it to other areas of the cell NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism for transport - not known if it is energy dependent or not, recycling and IC transport is important to get it to other areas of the cell (e.g. plasma membrane) NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism for transport - intracellular transport occurs, most details are unknown - see for example Varki glycobiology text or numerous reviews (PMID: 8206147) - extracellular transport is also made available since metabolites can get to outer plasma membrane NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Both human and Escherichia coli enzymes can use NADH in place of NADPH to a slight extent. IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: REMOVES EITHER ONE OR TWO GLUTAMYL RESIDUES WITH A REACTION (WILL ONLY REPRESENT 1) - last step from 5-glutamyl to monoglutamyl is in one step IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: REMOVES EITHER ONE OR TWO GLUTAMYL RESIDUES WITH A REACTION (WILL ONLY REPRESENT 1) IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: REMOVES EITHER ONE OR TWO GLUTAMYL RESIDUES WITH A REACTION (WILL ONLY REPRESENT 1) IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: REMOVES EITHER ONE OR TWO GLUTAMYL RESIDUES WITH A REACTION (WILL ONLY REPRESENT 1) - last step from 5-glutamyl to monoglutamyl is in one step IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: REMOVES EITHER ONE OR TWO GLUTAMYL RESIDUES WITH A REACTION (WILL ONLY REPRESENT 1) - last step from 5-glutamyl to monoglutamyl is in one step IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: REMOVES EITHER ONE OR TWO GLUTAMYL RESIDUES WITH A REACTION (WILL ONLY REPRESENT 1) IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: REMOVES EITHER ONE OR TWO GLUTAMYL RESIDUES WITH A REACTION (WILL ONLY REPRESENT 1) IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: REMOVES EITHER ONE OR TWO GLUTAMYL RESIDUES WITH A REACTION (WILL ONLY REPRESENT 1) IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: REMOVES EITHER ONE OR TWO GLUTAMYL RESIDUES WITH A REACTION (WILL ONLY REPRESENT 1) IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Cleaves the gamma-glutamyl peptide bond of glutathione conjugates, but maybe not glutathione itself. Converts leukotriene C4 (LTC4) to leukotriene D4 (LTD4). NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Converts leukotriene E4 (LTE4) to leukotriene D4 (LTE4). NJ

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC 2.4.1.226 NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC 2.4.1.226 NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC 2.4.1.226 NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC 2.4.1.226 NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC 2.4.1.225 NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC 2.4.1.225 NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC 2.4.1.225 NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC 2.4.1.225 NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC 2.4.1.223 NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC 2.4.1.224 NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC 2.4.1.224 NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC 2.4.1.224 NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC 2.4.1.224 NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: H symport into lysososome. See PMID: 2768261 and PMID: 10581036 ( for human evidence). Sialic acid storage disorders (due to transporter mutations) require import and export e.g. PMID: 2768266 NJ renamed from GLCURlt to GLCURtly - NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: lumped reaction, combination of 4-alpha-D-glucanotransferase (2.4.1.25) and amylo-alpha-1,6-glucosidase (3.2.1.33) NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TV (6/7/2005) Study in rat liver (Soboll, 1991)

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB based om PMID 10823827

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB m

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB use of FAD is not certain

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism, needed to transport glu-L out of ER in conversion of leuktrC4-> leuktrD4 NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB c

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IF

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB irreversible

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV Biochim Biophys Acta. 1980 Jun 6;598(3):588-94

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SMP Note no proton generation by the the reaction NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism for transport - intracellular transport occurs, most details are unknown - see for example Varki glycobiology text or numerous reviews (PMID: 8206147) - extracellular transport is also made available since metabolites can get to outer plasma membrane NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: peroxisomal version - NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD, TV This EC (1.6.4.2) is obsolete. The new EC is 1.8.1.7. http://www.genome.ad.jp/dbget-bin/www_bget?ec:1.6.4.2

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD, TV This EC (1.6.4.2) is obsolete. The new EC is 1.8.1.7. http://www.genome.ad.jp/dbget-bin/www_bget?ec:1.6.4.2

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TV (8-15-2003)

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TV (8-15-2003) Meister, A, Mitochondrial changes associated with glutathione deficiency, Biochimica et Biophysica Acta 1271 (1995) 35-42. The article reports that this is an active transport but doesn't not specify if it uses atp.

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism - NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD SAB e see Disussion section of PMID 15469854

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: tv

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: AMF

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: it

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: it

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Same as EC 1.1.1.157 SAB mito. some physiological

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Same as EC 1.1.1.157 SAB x

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM. inborn deficiency enzyme causes accumulation of substrate 3-hydroxy-2-methylbutyric acid

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Used to make Ubiquinone-10 EC 2.5.1.- IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: interaction between peroxisomes and ER (some enzymes on the outer membrane) NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IF

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD New assignment: EC-2.3.3.10 EC-4.1.3.5 (created 1961, deleted 2002). Enzyme Commission Made irreversible to match KEGG data for S. aureus

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD New assignment: EC-2.3.3.10 EC-4.1.3.5 (created 1961, deleted 2002). Enzyme Commission mitochondrial enzyme NJ Made irreversible to match KEGG data for S. aureus

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: diffusion NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TV

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TV NJ added peroxisomal version - see Olivier Biochimica et Biophysica Act 1529 (2000) 89-102

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV (4/28/2004) There are conflicting data on how many moles of NADPH consumed per mole of Biliverdine (Tenhunen 1969, Ryter, 2000). Heme oxygenase is a well known enzyme

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: The proton is located in the lysosome since it comes from oxidation of the NH3+ group in glucosamine. This reaction assumes that the other proton liberated from glucosamine reduces coa in the cytosol. NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: The proton is located in the lysosome since it comes from oxidation of the NH3+ group in glucosamine. This reaction assumes that the other proton liberated from glucosamine reduces coa in the cytosol. NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: The proton is located in the lysosome since it comes from oxidation of the NH3+ group in glucosamine. This reaction assumes that the other proton liberated from glucosamine reduces coa in the cytosol. NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: The proton is located in the lysosome since it comes from oxidation of the NH3+ group in glucosamine. This reaction assumes that the other proton liberated from glucosamine reduces coa in the cytosol. NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: direct enzymatic rates quantified in human brain tissue

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: microsomal NAD as cofactor HSD type 2 recheck/confirm comparmentalization - type 1: cytosol, types 2,3: microsomes NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: see Russell bile acid synthesis review paper in human recon citation db adamanski et al Steroids (1997) 62:159 notes cofactor NADP/NADPH use

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: see Russell bile acid synthesis review paper in human recon citation db adamanski et al Steroids (1997) 62:159 notes cofactor NADP/NADPH use

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Recombinant cDNA from human granulosa cells were purified and used in an enzyme assay, Km and Kcat values quantified

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: see PMID: 14643063 inferred use of O2 for oxidation - biochemical details have not yet been experimentally elucidated NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: kinetic studies done with recombinant human cDNA transfected into baculovirus

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Note that this reaction occurs in the endosome during endocytosis, but has been compartmentalized as lysosomal. NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: diffusion NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: diffusion NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: The reaction may be reversible. Strathern shows the reactions as irreversible. IF. Biochemical, Genetic

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Two reactions (ICDH1 and ICDH2) for isocitrate dehydrogenase

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Strathern indicates this reaction as irreversible. It may be reversible. Location is the peroxisomal matrix (MIPS). IF

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: The reaction may be reversible. Strathern shows the reaction as irreversible. IF

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: H symport into lysososome. See PMID: 2768261 and PMID: 10581036 (for human evidence). Sialic acid storage disorders (due to transporter mutations) require import and export e.g. PMID: 2768266 NJ renamed from GLCURlt to GLCURtly - NCD added IdoA reaction - NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: AR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: peroxisomal version - NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Some enzymes in this group hydrolyse a-L-arabinosides; some animal enzymes also hydrolyse b-D-fucosides and b-D-glucosides; cf. EC 3.2.1.108 lactase

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC 1.2.1.1 NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT. human enzymes overexpressed on E.coli, Pig Liver

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR- added irreversible form of LCAD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: this reaciton is only found in lactating mammary cells NCD

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: described in PMID: 3346220 and KEGG MM

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: This follows the convention of L-LACtm Also see LDL_D.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism, presumed diffusion NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism, presumed diffusion NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD ER version - NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: phosphatidyl choline degradation NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: lanosterol -> cholesterol pathway NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: lanosterol -> cholesterol pathway NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Converts leukotriene C4 (LTC4) to leukotriene F4 (LTF4). NJ

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: previous EC 2.5.1.37 EC: 4.4.1.20 NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Converts leukotriene D4 (LTD4) to leukotriene E4 (LTE4). unknown compartmentalization, cytosolic by default NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV (9/14/2004) added "m" to denote compartmentalization - NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV (9/14/2004) NJ added peroxismal and cytoplasmic reactions

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IF. Biochemical

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR- Based on reaction given for B. subtilis (Sekowska A and A. Danchin paper(2002) )

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IF

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IF

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: excretion of 3-mercaptolactate-cysteine disulfide (PMID: 6945862) MM

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Human Y/N: Y

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: peroxisomal version NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: this rxn also represents the enzymatic conversion or non-enzymatic fragmentation of g3p to mthgxl - NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR mitochondrial isoform - NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TV Also converts propanal to propanoyl-CoA

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: also EC 1.2.1.18 - NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM. biochemical activity measured in rat, sequence similarity found in human

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Note that this reaction is specific to beta-N-acetylhexosaminidase A and cannot be catalyzed by beta-N-acetylhexosaminidase B (or presumably beta-N-acetylhexosaminidase S). This is also a lumped reaction, representing the cleavage of GalNAc4S or GalNAc6S and N-acetylgalactosamine 4-sulfatase or 6-sulfatase. NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Note that this reaction is specific to beta-N-acetylhexosaminidase A and cannot be catalyzed by beta-N-acetylhexosaminidase B (or presumably beta-N-acetylhexosaminidase S). This is also a lumped reaction, representing the cleavage of GalNAc4S or GalNAc6S and N-acetylgalactosamine 4-sulfatase or 6-sulfatase. NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Note that this reaction is specific to beta-N-acetylhexosaminidase A and cannot be catalyzed by beta-N-acetylhexosaminidase B (or presumably beta-N-acetylhexosaminidase S). This is also a lumped reaction, representing the cleavage of GalNAc4S or GalNAc6S and N-acetylgalactosamine 4-sulfatase or 6-sulfatase. NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Note that this reaction is specific to beta-N-acetylhexosaminidase A and cannot be catalyzed by beta-N-acetylhexosaminidase B (or presumably beta-N-acetylhexosaminidase S). This is also a lumped reaction, representing the cleavage of GalNAc4S or GalNAc6S and N-acetylgalactosamine 4-sulfatase or 6-sulfatase. NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Note that this reaction is specific to beta-N-acetylhexosaminidase A and cannot be catalyzed by beta-N-acetylhexosaminidase B (or presumably beta-N-acetylhexosaminidase S). This is also a lumped reaction, representing the cleavage of GalNAc4S or GalNAc6S and N-acetylgalactosamine 4-sulfatase or 6-sulfatase. NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Note that this reaction is specific to beta-N-acetylhexosaminidase A and cannot be catalyzed by beta-N-acetylhexosaminidase B (or presumably beta-N-acetylhexosaminidase S). This is also a lumped reaction, representing the cleavage of GalNAc4S or GalNAc6S and N-acetylgalactosamine 4-sulfatase or 6-sulfatase. NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Note that this reaction is specific to beta-N-acetylhexosaminidase A and cannot be catalyzed by beta-N-acetylhexosaminidase B (or presumably beta-N-acetylhexosaminidase S). This is also a lumped reaction, representing the cleavage of GalNAc4S or GalNAc6S and N-acetylgalactosamine 4-sulfatase or 6-sulfatase. NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Note that this reaction is specific to beta-N-acetylhexosaminidase A and cannot be catalyzed by beta-N-acetylhexosaminidase B (or presumably beta-N-acetylhexosaminidase S). This is also a lumped reaction, representing the cleavage of GalNAc4S or GalNAc6S and N-acetylgalactosamine 4-sulfatase or 6-sulfatase. NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Note that this reaction is specific to beta-N-acetylhexosaminidase A and cannot be catalyzed by beta-N-acetylhexosaminidase B (or presumably beta-N-acetylhexosaminidase S). This is also a lumped reaction, representing the cleavage of GalNAc4S or GalNAc6S and N-acetylgalactosamine 4-sulfatase or 6-sulfatase. NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Note that this reaction is specific to beta-N-acetylhexosaminidase A and cannot be catalyzed by beta-N-acetylhexosaminidase B (or presumably beta-N-acetylhexosaminidase S). This is also a lumped reaction, representing the cleavage of GalNAc4S or GalNAc6S and N-acetylgalactosamine 4-sulfatase or 6-sulfatase. NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Note that this reaction is specific to beta-N-acetylhexosaminidase A and cannot be catalyzed by beta-N-acetylhexosaminidase B (or presumably beta-N-acetylhexosaminidase S). This is also a lumped reaction, representing the cleavage of GalNAc4S or GalNAc6S and N-acetylgalactosamine 4-sulfatase or 6-sulfatase. NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: diffusion - but unidirectional uptake into ER (to avoid loops w/ NAD/NADP) NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: diffusion - but unidirectional uptake into ER (to avoid loops w/ NAD/NADP) NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: diffusion - unidirectional to avoid NADP/NAD loops w/ free hydrogens NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: diffusion - but unidirectional output from ER (to avoid loops w/ NAD/NADP) NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: diffusion - unidirectional to avoid NADP/NAD loops w/ potential for free H NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: it

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: diffusion - but unidirectional output from ER (to avoid loops w/ NAD/NADP) NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Alpha-galactosidase B NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Alpha-galactosidase B NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC 3.2.1.- This reaction is my best guess at how the GlcNAc-beta-1,6-GalNAc linkage is cleaved. NCD

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: AMF TDV (8/25/2005, stoichiometry changed)

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Many nucleoside diphosphates (eight described) can act as acceptors. While many ribo- and deoxyribonucleoside triphosphates can act as donors, only ATP is chosen as a donor to minimize the number of total reactions.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Many nucleoside diphosphates (eight described) can act as acceptors. While many ribo- and deoxyribonucleoside triphosphates can act as donors, only ATP is chosen as a donor to minimize the number of total reactions. . Presence in the nucleus

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Many nucleoside diphosphates (eight described) can act as acceptors. While many ribo- and deoxyribonucleoside triphosphates can act as donors, only ATP is chosen as a donor to minimize the number of total reactions.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Many nucleoside diphosphates (eight described) can act as acceptors. While many ribo- and deoxyribonucleoside triphosphates can act as donors, only ATP is chosen as a donor to minimize the number of total reactions.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Many nucleoside diphosphates (eight described) can act as acceptors. While many ribo- and deoxyribonucleoside triphosphates can act as donors, only ATP is chosen as a donor to minimize the number of total reactions.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Many nucleoside diphosphates (eight described) can act as acceptors. While many ribo- and deoxyribonucleoside triphosphates can act as donors, only ATP is chosen as a donor to minimize the number of total reactions.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Many nucleoside diphosphates (eight described) can act as acceptors. While many ribo- and deoxyribonucleoside triphosphates can act as donors, only ATP is chosen as a donor to minimize the number of total reactions Presence in the nucleus

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Many nucleoside diphosphates (eight described) can act as acceptors. While many ribo- and deoxyribonucleoside triphosphates can act as donors, only ATP is chosen as a donor to minimize the number of total reactions.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Many nucleoside diphosphates (eight described) can act as acceptors. While many ribo- and deoxyribonucleoside triphosphates can act as donors, only ATP is chosen as a donor to minimize the number of total reactions Presence in the nucleus

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Many nucleoside diphosphates (eight described) can act as acceptors. While many ribo- and deoxyribonucleoside triphosphates can act as donors, only ATP is chosen as a donor to minimize the number of total reactions.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Many nucleoside diphosphates (eight described) can act as acceptors. While many ribo- and deoxyribonucleoside triphosphates can act as donors, only ATP is chosen as a donor to minimize the number of total reactions Presence in the nucleus

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Many nucleoside diphosphates (eight described) can act as acceptors. While many ribo- and deoxyribonucleoside triphosphates can act as donors, only ATP is chosen as a donor to minimize the number of total reactions.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Many nucleoside diphosphates (eight described) can act as acceptors. While many ribo- and deoxyribonucleoside triphosphates can act as donors, only ATP is chosen as a donor to minimize the number of total reactions Presence in the nucleus

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Many nucleoside diphosphates (eight described) can act as acceptors. While many ribo- and deoxyribonucleoside triphosphates can act as donors, only ATP is chosen as a donor to minimize the number of total reactions.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Many nucleoside diphosphates (eight described) can act as acceptors. While many ribo- and deoxyribonucleoside triphosphates can act as donors, only ATP is chosen as a donor to minimize the number of total reactions.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Many nucleoside diphosphates (eight described) can act as acceptors. While many ribo- and deoxyribonucleoside triphosphates can act as donors, only ATP is chosen as a donor to minimize the number of total reactions Presence in the nucleus

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: no gene or enzyme name known (in kegg) but reaction has to take place. IT

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: it

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: it

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: interaction between peroxisomes and ER (some enzymes on the outer membrane) NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Wide specificity for 5'-nucleotides Also see EC 3.1.3.31

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Wide specificity for 5'-nucleotides Also see EC 3.1.3.31

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IF

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: interaction between peroxisomes and ER (some enzymes on the outer membrane) NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: interaction between peroxisomes and ER (some enzymes on the outer membrane) NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: kh 1/7/03 SAB m

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: reaction sequence mx steps, grouped into single reaction uses adrenal ferredoxin NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: further oxidation of omega hydroxy LTB4 (leukotriene B4) stoichiometry inferrered - explicity primary literature refs not found NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT. human enzymes overexpressed on E.coli

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: for PC secretion into bile NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: 12372595 - expression; 16436377 - biochemical, tissue-specific

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: See PMID: 10856717 - flippase activity NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: See PMID: 10856717 - flippase activity no detailed data on which compartment ATP hydrolysis occurs, so for the time being assumed to be cytosolic NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: 17888579 - kinetic characterization of human cytosolic form; 8325643 - homology to rat; 17211624 - immunohistochemistry for expression

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IF

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SMP Net reaction same as described in Lehringer 334 NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: taken from KEGG map. No enzyme assigned, so assumed this is a non-enzymatic reaction. NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV changed name to"tm" to indicate mitochondrial transport NCD

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB m

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD FULLR corresponds to acyl/R groups in texts. NJ changed EC from 2.7.1.149 (pail5p) to 2.7.1.68 (pail4p) - NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD FULLR corresponds to acyl/R groups in texts. NJ changed EC from 2.7.1.149 (pail5p) to 2.7.1.68 (pail4p) - NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD Notice that contrary to some standards in texts, KEGG, etc, the Rtotal group accounts for the whole fatty acyl CoA (so the CHO only accounts for the core backbone), manner in which Rtotal was produced accounts for O and H balances. Formation of the Rtotal group (rxn flux)accounted for mass balance for CoA NJ changed EC from 2.7.1.149 (pail5p) to 2.7.1.68 (pail4p) - NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Notice that contrary to some standards in texts, KEGG, etc, the Rtotal group accounts for the whole fatty acyl CoA (so the CHO only accounts for the core backbone), manner in which Rtotal was produced accounts for O and H balances. Formation of the Rtotal group (rxn flux)accounted for mass balance for CoA NJ changed EC from 2.7.1.149 (pail5p) to 2.7.1.68 (pail4p) - NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: diffusion NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: phosphatidyl choline degradation NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: phosphatidyl choline degradation NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: peroxisomal version - NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: interaction between peroxisomes and ER (some enzymes on the outer membrane) NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC 3.5.1- KEGG RXN R02973 RM

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _01-25-05 based on Wang et al JBC, 1999,1 274(21), 14875-14888. IT 03-07-05:replaced IT: now based on Balamurugan et al, 2005, Am J Physiol Renal Physiol, 288, F823-831,2005

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IF

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV Short-chain fatty acid can diffuse through mitochondrial membrane

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: diffusion NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: diffusion NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD. Benzodiazepine receptor PBR see also 17168567

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: RS/TV (6/3/05) Peroxidases can act on a variety of substrates which are oxidized, not just methanol.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Mechanism not known, see PMID 11591435 for justification. NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Mechanism not known, see PMID 11591435 for justification. NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Mechanism not known, see PMID 11591435 for justification. NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: modified from TV version for hs NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: See PMID: 10856717 - flippase activity NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: See PMID: 10856717 - flippase activity no detailed data on which compartment ATP hydrolysis occurs, so for the time being assumed to be cytosolic NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: phosphatidylcholine as substrate NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: This reaction takes place in skin and needs UV 290-305. based on Vitamins, G.F.M. Ball,2004, Blackwell publishing, 1st ed (book) pg.194 IT

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR- added reversible form of PYNP2

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IF changed name from "tm" to "t2m" - NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism for transport - carnitine transporters not found, unknown mechanism intracellularly, however there must be a mechanism for FA transport NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC 2.8.2- NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC 2.8.2- NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC 2.8.2- NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC 2.8.2- NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC 2.8.2.- NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: intracellular transport, mechanism details not presently known NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: intracellular transport, mechanism details not presently known NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SCP has two transcripts, second isoform specific to peroxisomes, first is specific for cyt and mit need to double check stoichiometry - reaction cofactors (additional coa + release of prop coa) from BM (Roche) Biochemical Pathways NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB based on PMID 12845534

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SGPL1 gene as per GeneCards states that hexadecanal is produced - the only way to do this and to maintain charge balance would be to have H2 gas as substrate - remarkably implausible. Due to lack of information to indicate otherwise, added water to breakdown components into ethamp and palmitate NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: AMF EC: 1.1.1.272

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SOAT11 and SOAT12 are templates, customized rxns can be formed particular ester moieties. NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism for transport, may be vesicular/caveolar/other intracellular transport and extracellular export mechanisms must exist - see for example: PMID: 15585321 NJ

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism - reflects interaction between different stages of endosomes and cytoplasm NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism, however sphingosine manages to get in different compartments of cells. NOT presumed to be flip-flop. NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism, however sphingosine manages to get in different compartments of cells. NOT presumed to be flip-flop. NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism for transport - however must get to other intracellular compartments (e.g. lysosome for degradation) NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism for transport - however must get to other intracellular compartments (e.g. lysosome for degradation) NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism, however sphs1p is known to have intracellular and extracellular activity and signal transduction functions (PMID: 10751414). NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism, however sphs1p is known to have intracellular and extracellular activity and signal transduction functions (PMID: 10751414 or PMID: 15585321). NJ

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TV (8-15-2003)

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: This is a lumped reaction: Rxn 1: 2 frdp -> 2 ppi + presqualene diphosphate Rxn 2: presqualene diphosphate + NADPH -> squalene + NADP NCD ER version - NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: see PMID: 14643063 there are actually two types, but the difference between them lies in optimal pH function - grouped as one reaction at his point to eliminate redundancy. NADP known to be cofactor NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: there are actually two types, but the difference between them lies in optimal pH function - grouped as one reaction at his point to eliminate redundancy. NADP known to be cofactor NJ. human 5alpha-HSD activity determined in transfected COS cells using C-14 labelled testosterone as substrate

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD. Biochemical, Genetic

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IF

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MIPS: cofactor ATP IF changed EC from 6.2.1.4 to 6.2.1.5 - NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT reaction involved in formation of 4-hydroxybenzoate from tyrosine.

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB based on PMID 10727395

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: TDV (2-6-2003)

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD,IT

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _01-25-05 IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB see Kanai and Hediger 2004 (2003), PMID 14530974

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: also EC 2.7.6.2 - NCD

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: interaction between peroxisomes and ER (some enzymes on the outer membrane) NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Xia et al, 2003, JBC, 2141-2146

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Xia et al, 2003, JBC, 2141-2146

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB unlumped version of TRPHYDRO1

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: specific mechanism not known, proton dependence for trans-mit transport has been suggested, however directionality and stoichiometry has not yet been elucidated. see PMID: 12770731 and others NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism for transport - there are UDPACGAL-translocators for ER and Golgi, however no info on lysosomal - poor support for this NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: unknown mechanism for transport - not known if it is energy dependent or not, recycling and IC transport is important to get it to other areas of the cell (e.g. plasma membrane) - translocators have been found for ER and Golgi - none found for lysosome yet so non-mechanistic transporter added - in future this will need to be revised _when_ a translocator is found NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB balanced

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: This reaction takes place in skin and needs body temperature based on Vitamins, G.F.M. Ball,2004, Blackwell publishing, 1st ed (book) pg.194 IT

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: from uniprot and lit - see human recon lit refs divalent cation requirement - unclear which one, reaction inhibited in the presence of EDTA (may just be MgATP or MgATP) - see Kelley and Vessey Biochimica et Biophysica Acta (1994) 1209: 51-55 temporarily will have H+ balance reaction NJ

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: details of metabolism, etc are unknown - allwoed to be exported presently - unknown mechanism NJ

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: cholesterol precursor, transport by "diffusion" -> actually beleived to be flip-flop mechanism (PMID: 12840657). NJ

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: immunocytochemistry, subcellular fractionation, and electron microscopy have demonstrated that xylosylation begins in the ER and continues in the early Golgi [Kearns, J Biol Chem 1993] PMID: 8496172 NCD

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT - fixed proton

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT - fixed proton

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: RE1814X

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: UGLCNACtg but different compartment

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT - fixed proton

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT - fixed proton

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT - fixed proton

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT - fixed proton

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT - fixed proton

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT - fixed proton

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT - fixed proton

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT - fixed proton

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Recin 1 had irreversible version - PI35P3P - GPR from PI35P3P was added - May 2011 IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT - fixed proton

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: MM

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: Hunt MC, Alexson SEH. (2008). Progress in Lipid Research 47: 405-21

+

Confidence Level: 0.0

+

NOTES: dicarboxylic coa synthetase, origin and gene not known

+ +
+ + + + + + + + + + +
+ + + +

References: Glatz JFC, Luiken JJFP, Bonen A. (2010). Physiological Reviews 90: 367-417, Kamp F, Hamilton JA. (2006). Prostaglandins, Leukotrienes and Essential Fatty Acids 75: 149-59, PMCID: PMC2785172, Evtodienko VY, Bondarenko DI, Antonenko YN. (1999). Biochimica et Biophysica Acta (BBA) - Biomembranes 1420: 95-103

+

Confidence Level: 0.0

+

NOTES: simple diffusion of fatty acids freely across membranes

+ +
+ + + + + + +
+ + + +

References: Westin M, Hunt M, Alexson S. (2008). Cellular and Molecular Life Sciences 65: 982-90,

+

Confidence Level: 0.0

+

NOTES: alternatively peroxisomal carnitine O-octanoyltransferase may convert adipoyl coa into adipoyl carnitine and excreted out. Thioesterases and CRAT/CROT show same substrate specificty and similar Vmax and Km values, however author suggested there is no competition as they are expressed differentially in different tissues.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: Westin MAK, Hunt MC, Alexson SEH. (2005). Journal of Biological Chemistry 280: 38125-32

+

Confidence Level: 0.0

+

NOTES: human peroxisomal thioesterases are ACOT-4 and ACOT-8. ACOT 4 is specific for C4DC and C5DC, where as ACOT-8 catalyzes wide range of substrates. One proton added to the product for balancing

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: Westin M, Hunt M, Alexson S. (2008). Cellular and Molecular Life Sciences 65: 982-90. doi:10.1006/mgme.2000.3055,doi:10.1006/bbrc.1999.1340,biochimica et biophysica acta 1546 (2001) 21-43

+

Confidence Level: 0.0

+

NOTES: acyl carnitines transported by CACT.

+ +
+ + + + + + + + + +
+ + + +

References: doi:10.1016/j.physletb.2003.10.071

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: Westin MAK, Hunt MC, Alexson SEH. (2005). Journal of Biological Chemistry 280: 38125-32

+

Confidence Level: 0.0

+

NOTES: human peroxisomal thioesterases are ACOT-4 and ACOT-8. ACOT 4 is specific for C4DC and C5DC, where as ACOT-8 catalyzes wide range of substrates. One proton added to the product for balancing

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: Hunt MC, Alexson SEH. (2008). Progress in Lipid Research 47: 405-21

+

Confidence Level: 0.0

+

NOTES: dicarboxylic coa synthetase, origin and gene not known

+ +
+ + + + + + + + + + +
+ + + +

References: Glatz JFC, Luiken JJFP, Bonen A. (2010). Physiological Reviews 90: 367-417, Kamp F, Hamilton JA. (2006). Prostaglandins, Leukotrienes and Essential Fatty Acids 75: 149-59, PMCID: PMC2785172, Evtodienko VY, Bondarenko DI, Antonenko YN. (1999). Biochimica et Biophysica Acta (BBA) - Biomembranes 1420: 95-103

+

Confidence Level: 0.0

+

NOTES: simple diffusion of fatty acids freely across membranes

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: biochemical and biophysical research communications 263,213-218(1999),biochimica et biophysica acta 1546(2001)21-43

+

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

References: PMCID: PMC2914534

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: Biochemica et Biophysica Acta 1486(2000) 1-17, Eur. J. Biochem. 244, 1-14 (1997) FEBS 1997, Biochemica et Biophysica Acta 1546(2001) 21-43.

+

Confidence Level: 0.0

+

NOTES: CPT-2 reaction

+ +
+ + + + + + + + + + + +
+ + + +

References: Westin M, Hunt M, Alexson S. (2008). Cellular and Molecular Life Sciences 65: 982-90. doi:10.1006/mgme.2000.3055,doi:10.1006/bbrc.1999.1340,biochimica et biophysica acta 1546 (2001) 21-43

+

Confidence Level: 0.0

+

NOTES: acyl carnitines transported by CACT.

+ +
+ + + + + + + + + +
+ + + +

References: biochimica et biophysica acta 1546(2001)21-43

+

Confidence Level: 0.0

+

NOTES: should be noted that shortchain acylcarnitines are freely permeable accross membrane

+ +
+ + + + + + + + + +
+ + + +

References: biochimica et biophysica acta 1546(2001)21-43

+

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

References: the journal of biological chemistry volume280,no.1,issue of january,pp.738-744,2005

+

Confidence Level: 0.0

+

NOTES: crot shows activity for C6 to C10 fatty acylcoa, however some amont of activity for short chain fattyacylcoa also. The exit from peroxisomes can also be at the hexanoylcoa stage which is more frequently observed.however some levels of activity is also seen at the bytyrylcoa stage.

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: the journal of biological chemistry,vol 280, no1,issue of january 7,pp 738-744,2005

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

References: biochimica et biophysica acta 1546(2001)21-43

+

Confidence Level: 0.0

+

NOTES: short and medium chain acylcarnitines are also freely permeable accros the membrane.

+ +
+ + + + + + + + + +
+ + + +

References: Westin M, Hunt M, Alexson S. (2008). Cellular and Molecular Life Sciences 65: 982-90. doi:10.1006/mgme.2000.3055,doi:10.1006/bbrc.1999.1340,biochimica et biophysica acta 1546 (2001) 21-43

+

Confidence Level: 0.0

+

NOTES: acyl carnitines transported by CACT.

+ +
+ + + + + + + + + +
+ + + +

References: doi:10.1016/j.physletb.2003.10.071

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: doi:10.1016/j.physletb.2003.10.071

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + +
+ + + +

References: doi:10.1006/mgme.2000.3055,doi:10.1006/bbrc.1999.1340,biochimica et biophysica acta 1546 (2001) 21-43

+

Confidence Level: 0.0

+

NOTES: mentioned in recon1 as SCP22x. CACT activity has been reported in peroxisomes and they mediate transfer of acylcarnitine from peroxisomes to cytosol and then furher uptake into mitochondria.CACT are concentration dependant,uniport transporters acting in ping-pong mechanism. Synonym is CACT

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: free fatty acids transported by simple diffusion, fatty acid transport proteins may be involved. Depends on the physiological concentration of these fatty acids.

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: free fatty acids transported by simple diffusion, fatty acid transport proteins may be involved. Depends on the physiological concentration of these fatty acids.

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+

NOTES: acyl coA dehydrogenase enzyme catalyzes this reaction in mitochondria.first step of beta oxidation

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: peroxisomal acyl coA oxidase reaction.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: peroxisomal beta oxidation reaction.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: PNAS August 1, 1992 vol. 89 no. 15 6673-6677, FEBS LETTERS vol.215 no.2 228-232

+

Confidence Level: 0.0

+

NOTES: delta3-cis->delta 2-trans isomerase

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: 2,4-dienoyl coA reductase catalyzes this reaction in mitochondria.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: "Journal of Molecular Biology, Volume 342, Issue 4, 24 September 2004, Pages 1197-1208"

+

Confidence Level: 0.0

+

NOTES: cis-delta3->trans-delta2 isomerase

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: 2,4-dienoyl coA reductase

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+

NOTES: mitochondrial beta oxidation.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+

NOTES: mitochondrial beta oxidation

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: PNAS August 1, 1992 vol. 89 no. 15 6673-6677, FEBS LETTERS vol.215 no.2 228-232

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+

NOTES: one cycle of beta oxidation occurs in mitochondria

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: "Journal of Molecular Biology, Volume 342, Issue 4, 24 September 2004, Pages 1197-1208"

+

Confidence Level: 0.0

+

NOTES: delta3-cis/trans-->delta2-trans-enoyl coA isomerase enzyme catalyzes this reaction in mitochondria.

+ +
+ + + + + + + + + +
+ + + +

References: PNAS August 1, 1992 vol. 89 no. 15 6673-6677, FEBS LETTERS vol.215 no.2 228-232

+

Confidence Level: 0.0

+

NOTES: delta3-cis->delta 2-trans isomerase

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: "Journal of Molecular Biology, Volume 342, Issue 4, 24 September 2004, Pages 1197-1208"

+

Confidence Level: 0.0

+

NOTES: cis-delta3->trans-delta2 isomerase

+ +
+ + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+

NOTES: mitochondrial beta oxidation.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: HMDB00387

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: The Tohoku Journal of Experimental Medicine.Vol. 221 (2010) , No. 3 pp.191-195

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: Westin M, Hunt M, Alexson S. (2008). Cellular and Molecular Life Sciences 65: 982-90. doi:10.1006/mgme.2000.3055,doi:10.1006/bbrc.1999.1340,biochimica et biophysica acta 1546 (2001) 21-43

+

Confidence Level: 0.0

+

NOTES: acyl carnitines transported by CACT.

+ +
+ + + + + + + + + +
+ + + +

References: Korman SH, Waterham HR, Gutman A, Jakobs C, Wanders RJA. (2005). Molecular Genetics and Metabolism 86: 337-43

+

Confidence Level: 0.0

+

NOTES: elevated in urine in C-12 dicarboxylic aciduria

+ +
+ + + + + + + + + + + + + + + +
+ + + +

References: Westin M, Hunt M, Alexson S. (2008). Cellular and Molecular Life Sciences 65: 982-90,

+

Confidence Level: 0.0

+

NOTES: alternatively peroxisomal carnitine O-octanoyltransferase may convert adipoyl coa into adipoyl carnitine and excreted out. Thioesterases and CRAT/CROT show same substrate specificty and similar Vmax and Km values, however author suggested there is no competition as they are expressed differentially in different tissues.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+

NOTES: mitochondrial beta oxidation

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: peroxisomal beta oxidation reaction

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+

NOTES: mitochondrial beta oxidation.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: HMDB02095,

+

Confidence Level: 0.0

+

NOTES: as a C3DC.HMDB02095,PMID: 12651823

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+

NOTES: mitochondrial beta oxidation

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: peroxisomal beta oxidation reaction

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: PMCID: PMC2702680

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: peroxisomal acyl coA oxidase reaction.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: "Journal of Molecular Biology, Volume 342, Issue 4, 24 September 2004, Pages 1197-1208"

+

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

References: PNAS August 1, 1992 vol. 89 no. 15 6673-6677, FEBS LETTERS vol.215 no.2 228-232

+

Confidence Level: 0.0

+

NOTES: delta3-cis->delta 2-trans isomerase

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+

NOTES: beta oxidation

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: 2,4-dienoyl coA reductase

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: PMCID: PMC2702680

+

Confidence Level: 0.0

+

NOTES: acyl coA dehydrogenase

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: "Journal of Molecular Biology, Volume 342, Issue 4, 24 September 2004, Pages 1197-1208"

+

Confidence Level: 0.0

+

NOTES: cis-delta3->trans-delta2 isomerase

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: 2,4-dienoyl coA reductase

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+

NOTES: mitochondrial beta oxidation

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: to acetyl coA and accumulates and then combines with free carnitine and ultimately excreated in urine

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: PMCID:PMC1152672

+

Confidence Level: 0.0

+

NOTES: the enzyme is not yet charecterized at the molecular level.this evidence taken from mouse experiment.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+

NOTES: mitochondrial beta oxidation

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: harpers biochemistry-25th edition-page no.242.

+

Confidence Level: 0.0

+

NOTES: "the dehydrogenase action can also be catalyzed by ACAD9 gene(Biochemical and Biophysical Research Communications,Volume 297, Issue 4, 4 October 2002, Pages 1033-1042)

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+

NOTES: mitochondrial beta oxidation

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+

NOTES: beta oxidation

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: journal of lipid research 1998 vol 39 pages 2161-2171

+

Confidence Level: 0.0

+

NOTES: peroxisomal beta oxidation reaction

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: "Journal of Molecular Biology, Volume 342, Issue 4, 24 September 2004, Pages 1197-1208 5.3.3.8

+

Confidence Level: 0.0

+

NOTES: cis-delta3->trans-delta2 isomerase

+ +
+ + + + + + + + + +
+ + + +

References: PNAS August 1, 1992 vol. 89 no. 15 6673-6677, FEBS LETTERS vol.215 no.2 228-232

+

Confidence Level: 0.0

+

NOTES: delta3-cis->delta 2-trans isomerase

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: "Journal of Molecular Biology, Volume 342, Issue 4, 24 September 2004, Pages 1197-1208"

+

Confidence Level: 0.0

+

NOTES: cis-delta3->trans-delta2 isomerase

+ +
+ + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: peroxisomal acyl coA oxidase reaction.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: journal of lipid research 1998 vol 39 pages 2161-2171

+

Confidence Level: 0.0

+

NOTES: peroxisomal beta oxidation reaction

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+

NOTES: one cycle of beta oxidation

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: journal of lipid research 1998 vol 39 pages 2161-2171

+

Confidence Level: 0.0

+

NOTES: peroxisomal beta oxidation

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: PMCID: PMC2702680

+

Confidence Level: 0.0

+

NOTES: acyl coA dehydrogenase

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: peroxisomal acyl coA oxidase reaction.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: "Journal of Molecular Biology, Volume 342, Issue 4, 24 September 2004, Pages 1197-1208"

+

Confidence Level: 0.0

+

NOTES: cis-delta3->trans-delta2 isomerase

+ +
+ + + + + + + + + +
+ + + +

References: PNAS August 1, 1992 vol. 89 no. 15 6673-6677, FEBS LETTERS vol.215 no.2 228-232

+

Confidence Level: 0.0

+

NOTES: delta3-cis->delta 2-trans isomerase

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+

NOTES: one cycle of beta oxidation

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: 2,4-dienoyl coA reductase

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: 2,4-dienoyl coA reductase

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: PMCID: PMC2702680

+

Confidence Level: 0.0

+

NOTES: acyl coA dehydrogenase

+ +
+ + + + + + + + + + + +
+ + + +

References: "Journal of Molecular Biology, Volume 342, Issue 4, 24 September 2004, Pages 1197-1208"

+

Confidence Level: 0.0

+

NOTES: cis-delta3->trans-delta2 isomerase

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: 2,4-dienoyl coA reductase

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: "Journal of Molecular Biology, Volume 342, Issue 4, 24 September 2004, Pages 1197-1208"

+

Confidence Level: 0.0

+

NOTES: cis-delta3->trans-delta2 isomerase

+ +
+ + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: PMCID:PMC1152672

+

Confidence Level: 0.0

+

NOTES: undergoes series of beta oxidation cycles to generate C8DC,C6DC,C4DC and acetate. The extra one proton was obtained in the product, from the aldehyde form of the omega-hydroxy palmitic acid (i.e. An intermediate not shown in this reaction). This was done in-order to balance the reaction and also to obtain the dicarboxylic form of the palmitic acid.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: first cycle of mitochondrial beta oxidation.

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: 2,4-dienoyl coA reductase

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+

NOTES: mitochondrial beta oxidation

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: "Journal of Molecular Biology, Volume 342, Issue 4, 24 September 2004, Pages 1197-1208"

+

Confidence Level: 0.0

+

NOTES: cis-delta3->trans-delta2 isomerase

+ +
+ + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+

NOTES: mitochondrial beta oxidation

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+

NOTES: mitochondrial beta oxidation

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: international journal of molecular medicine 19: 81-87, 2007.

+

Confidence Level: 0.0

+

NOTES: mitochondrial beta oxidation

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: peroxisomal beta oxidation

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: acyl coA binding protein is localized in cytosol, nucelus, golgi, E.R mitochondrial inter memebrane space. In mitochondria its released when the integrity of the organelle is compromised. It has wide role in lipid metabolism, also acts as a coA transporter between different cellular compartments. can transport accumulated acyl coAs from cutosol into mitochondria for beta oxidation or into cytosol for either transport into other compartemnts or for elliciting signalling cascades.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: free fatty acids transported by simple diffusion, fatty acid transport proteins may be involved. Depends on the physiological concentration of these fatty acids.

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: required for the production of short chain DC in peroxisomes. Alternatively C16 DC can also be produced from C18DC and other higher DC. Peroxisomes does not contain ACBP, so this reaction is irrerversible

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: Biochemica et Biophysica Acta 1486(2000) 1-17, Eur. J. Biochem. 244, 1-14 (1997) FEBS 1997, Biochemica et Biophysica Acta 1546(2001) 21-43.

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + +
+ + + +

References: Biochemica et Biophysica Acta 1486(2000) 1-17, Eur. J. Biochem. 244, 1-14 (1997) FEBS 1997, Biochemica et Biophysica Acta 1546(2001) 21-43.

+

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

References: Biochemica et Biophysica Acta 1486(2000) 1-17, Eur. J. Biochem. 244, 1-14 (1997) FEBS 1997, Biochemica et Biophysica Acta 1546(2001) 21-43.

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: Westin MAK, Hunt MC, Alexson SEH. (2005). Journal of Biological Chemistry 280: 38125-32

+

Confidence Level: 0.0

+

NOTES: human peroxisomal thioesterases are ACOT-4 and ACOT-8. ACOT 4 is specific for C4DC and C5DC, where as ACOT-8 catalyzes wide range of substrates. One proton added to the product for balancing

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: already present in recon 1 but without coupled atp hydrolysis

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: Hunt MC, Alexson SEH. (2008). Progress in Lipid Research 47: 405-21

+

Confidence Level: 0.0

+

NOTES: dicarboxylic coa synthetase, origin and gene not known

+ +
+ + + + + + + + + + +
+ + + +

References: Glatz JFC, Luiken JJFP, Bonen A. (2010). Physiological Reviews 90: 367-417, Kamp F, Hamilton JA. (2006). Prostaglandins, Leukotrienes and Essential Fatty Acids 75: 149-59, PMCID: PMC2785172, Evtodienko VY, Bondarenko DI, Antonenko YN. (1999). Biochimica et Biophysica Acta (BBA) - Biomembranes 1420: 95-103

+

Confidence Level: 0.0

+

NOTES: simple diffusion of fatty acids freely across membranes

+ +
+ + + + + + +
+ + + +

References: Westin M, Hunt M, Alexson S. (2008). Cellular and Molecular Life Sciences 65: 982-90,

+

Confidence Level: 0.0

+

NOTES: alternatively peroxisomal carnitine O-octanoyltransferase may convert adipoyl coa into adipoyl carnitine and excreted out. Thioesterases and CRAT/CROT show same substrate specificty and similar Vmax and Km values, however author suggested there is no competition as they are expressed differentially in different tissues.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: Westin MAK, Hunt MC, Alexson SEH. (2005). Journal of Biological Chemistry 280: 38125-32

+

Confidence Level: 0.0

+

NOTES: human peroxisomal thioesterases are ACOT-4 and ACOT-8. ACOT 4 is specific for C4DC and C5DC, where as ACOT-8 catalyzes wide range of substrates. One proton added to the product for balancing

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: Glatz JFC, Luiken JJFP, Bonen A. (2010). Physiological Reviews 90: 367-417, Kamp F, Hamilton JA. (2006). Prostaglandins, Leukotrienes and Essential Fatty Acids 75: 149-59, PMCID: PMC2785172, Evtodienko VY, Bondarenko DI, Antonenko YN. (1999). Biochimica et Biophysica Acta (BBA) - Biomembranes 1420: 95-103

+

Confidence Level: 0.0

+

NOTES: simple diffusion of fatty acids freely across membranes

+ +
+ + + + + + +
+ + + +

References: Westin M, Hunt M, Alexson S. (2008). Cellular and Molecular Life Sciences 65: 982-90. doi:10.1006/mgme.2000.3055,doi:10.1006/bbrc.1999.1340,biochimica et biophysica acta 1546 (2001) 21-43

+

Confidence Level: 0.0

+

NOTES: acyl carnitines transported by CACT.

+ +
+ + + + + + + + + +
+ + + +

References: Westin M, Hunt M, Alexson S. (2008). Cellular and Molecular Life Sciences 65: 982-90,

+

Confidence Level: 0.0

+

NOTES: alternatively peroxisomal carnitine O-octanoyltransferase may convert adipoyl coa into adipoyl carnitine and excreted out. Thioesterases and CRAT/CROT show same substrate specificty and similar Vmax and Km values, however author suggested there is no competition as they are expressed differentially in different tissues.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: Hunt MC, Alexson SEH. (2008). Progress in Lipid Research 47: 405-21

+

Confidence Level: 0.0

+

NOTES: dicarboxylic coa synthetase, origin and gene not known

+ +
+ + + + + + + + + + +
+ + + +

References: Westin M, Hunt M, Alexson S. (2008). Cellular and Molecular Life Sciences 65: 982-90,

+

Confidence Level: 0.0

+

NOTES: alternatively peroxisomal carnitine O-octanoyltransferase may convert adipoyl coa into adipoyl carnitine and excreted out. Thioesterases and CRAT/CROT show same substrate specificty and similar Vmax and Km values, however author suggested there is no competition as they are expressed differentially in different tissues.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: Westin MAK, Hunt MC, Alexson SEH. (2005). Journal of Biological Chemistry 280: 38125-32

+

Confidence Level: 0.0

+

NOTES: human peroxisomal thioesterases are ACOT-4 and ACOT-8. ACOT 4 is specific for C4DC and C5DC, where as ACOT-8 catalyzes wide range of substrates. One proton added to the product for balancing

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: PMCID: PMC1412501,

+

Confidence Level: 0.0

+

NOTES: Dipeptides and tripeptides enter the brush border of the intestinal mucosal cells, where they are hydrolyzed to free amino acids, which are then transported into hepatic portal vein. Peptides entering by transcellular or paracellular mechanisms elicit allergic reactions to food (Robert K. Murray, David A. Bender, Kathleen M. Botham, Peter J. kennelly, Victor W. Rodwell, P. Anthony Weil (2009) 28th edition, Harpers illustrated biochemistry,Mc Graw Hill, page 462). formation and hydrolysis of diglycine is a reversible process (David L. Nelson, Michael M. Cox, Lehniniger principles of biochemistry (2000), 3rd edition, worth publishers,page 69, figure 3a). CN1 is expressed in brain where as CN2 is more ubiquitously expressed (PMID: 12473676).

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: y+LAT1 and y+LAT2 transporters requires CD98 for sequesterization to the plasma membrane. Acts as an amino acid exchanger, with influx of neutral aminoa acids and efflux of cationic amino acid, requires Na+ for optimal activity. Can also operate with H+ in absence of Na+ (PMID: 11546643).

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: G.F.M. Ball (2006) Vitamins their role in the human body, Blackwell publishing, chapter 19, page 395-398,

+

Confidence Level: 0.0

+

NOTES: SVCT1 and SVCT2 differ in their tissue distribution, SVCT1 is more ubiquitously expressed, where as SVCT1 is confined to intestine, liver and kidney. The Na+ symport transport is energized by Na+/K+ ATPase, therefore its a secondary active transport ( G.F.M. Ball (2006) Vitamins their role in the human body, Blackwell publishing, chapter 19, page 395-398). Vitamin C is absorbed only in ascorbate form, can be oxidized into dehydroascorbate, and can then enter the blood stream (Sareen S. Gropper, Jack L. Smith, James L. Groff (2009) Advanced nutrition and human metabolism, Wadsworth cengage learning, 5th edition, page 312-313).

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: G.F.M. Ball (2006) Vitamins their role in the human body, Blackwell publishing, chapter 16, page 339-340.

+

Confidence Level: 0.0

+

NOTES: biotin release from the enterocytes along the baso-lateral membrane is carrier protein mediated, Na+ independant and eletroneutral (exact protein involved needs to be further investigated). However pantothenic acid seems to compete with biotin for uptake. also in the presence of pantothenate, more amount of biotin exits enterocytes (PMID: 10064315).

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

References: PMCID: PMC1665133,

+

Confidence Level: 0.0

+

NOTES: SNAT5 performs both symport with sodium and antiport with proton, for the net transport of neutral amino acid into the cell. Cellular localization has been reported in stomach, brain, liver, lung, small intestine, spleen, colon and kidney. (PMID: 12845534)

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: y+LAT1 and y+LAT2 transporters requires CD98 for sequesterization to the plasma membrane. Acts as an amino acid exchanger, with influx of neutral aminoa acids and efflux of cationic amino acid, requires Na+ for optimal activity. Can also operate with H+ in absence of Na+ (PMID: 11546643).

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: PMCID: PMC1412501,

+

Confidence Level: 0.0

+

NOTES: Dipeptides and tripeptides enter the brush border of the intestinal mucosal cells, where they are hydrolyzed to free amino acids, which are then transported into hepatic portal vein. Peptides entering by transcellular or paracellular mechanisms elicit allergic reactions to food (Robert K. Murray, David A. Bender, Kathleen M. Botham, Peter J. kennelly, Victor W. Rodwell, P. Anthony Weil (2009) 28th edition, Harpers illustrated biochemistry,Mc Graw Hill, page 462). formation and hydrolysis of diglycine is a reversible process (David L. Nelson, Michael M. Cox, Lehniniger principles of biochemistry (2000), 3rd edition, worth publishers,page 69, figure 3a). CN1 is expressed in brain where as CN2 is more ubiquitously expressed (PMID: 12473676).

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: PMCID: PMC1665133,

+

Confidence Level: 0.0

+

NOTES: SNAT5 performs both symport with sodium and antiport with proton, for the net transport of neutral amino acid into the cell. Cellular localization has been reported in stomach, brain, liver, lung, small intestine, spleen, colon and kidney. (PMID: 12845534)

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: PMCID: PMC1665133,

+

Confidence Level: 0.0

+

NOTES: SNAT5 performs both symport with sodium and antiport with proton, for the net transport of neutral amino acid into the cell. Cellular localization has been reported in stomach, brain, liver, lung, small intestine, spleen, colon and kidney. (PMID: 12845534)

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: y+LAT1 and y+LAT2 transporters requires CD98 for sequesterization to the plasma membrane. Acts as an amino acid exchanger, with influx of neutral aminoa acids and efflux of cationic amino acid, requires Na+ for optimal activity. Can also operate with H+ in absence of Na+ (PMID: 11546643).

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: y+LAT1 and y+LAT2 transporters requires CD98 for sequesterization to the plasma membrane. Acts as an amino acid exchanger, with influx of neutral aminoa acids and efflux of cationic amino acid, requires Na+ for optimal activity. Can also operate with H+ in absence of Na+ (PMID: 11546643).

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: both pig(E.C. 3.4.11.5) and human (3.4.11.1) amino peptidase have similar amino acid sequence and catalytic properties (PMID: 1908238)

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: y+LAT1 and y+LAT2 transporters requires CD98 for sequesterization to the plasma membrane. Acts as an amino acid exchanger, with influx of neutral aminoa acids and efflux of cationic amino acid, requires Na+ for optimal activity. Can also operate with H+ in absence of Na+ (PMID: 11546643).

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Confidence Level: 0.0

+

NOTES: y+LAT1 and y+LAT2 transporters requires CD98 for sequesterization to the plasma membrane. Acts as an amino acid exchanger, with influx of neutral aminoa acids and efflux of cationic amino acid, requires Na+ for optimal activity. Can also operate with H+ in absence of Na+ (PMID: 11546643).

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

References: Sareen S. Gropper, jack L. Smith, James L. Groff (2009) Wadaworth cengage learning, Advanced nutrition and human metabolism, 5th edition, page 142-148.

+

Confidence Level: 0.0

+

NOTES: transported in chylomicrons into lymph

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: y+LAT1 and y+LAT2 transporters requires CD98 for sequesterization to the plasma membrane. Acts as an amino acid exchanger, with influx of neutral aminoa acids and efflux of cationic amino acid, requires Na+ for optimal activity. Can also operate with H+ in absence of Na+ (PMID: 11546643).

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: not much is known about the pantothenic acid exit across the basolateral membrane. Diffusion reaction is hypothetical. However, uptake of pantothenate by RBCs takes place by simple diffusion (G.F.M. Ball (2006) Vitamins their role in the human body, Blackwell publishing, chapter 15, page 329.).

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: ASCT1 helps in absorption of hydroxy-proline by aiding in its exit from the enterocytes into the blood stream. The ASCT1 transport system operates as an obligatory amino acid exchanger, Na+ depedant manner. Alaine is the preeferred susbstrate.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

References: no specific transporter for exit of D-alanine could be found, so diffusion mechanism is assumed.

+

Confidence Level: 0.0

+

NOTES: no specific transporter for exit of D-alanine could be found, so diffusion mechanism is assumed.

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

References: Kim E. Barrett, Mark Donowitz (2001) Gastrointestinal transport: Molecular physiology, Academic press, A harcourt science and technology company, chapter 10, pages 389-391.

+

Confidence Level: 0.0

+

NOTES: ASCT-1 transport system operates at the basolateral surface, acts as an amino acid exchanger. Preferred substrates are small neutral amino acids, however shown to have transport proline and hydroxy-proline. At acidic ph also transports aspartate and glutamate. the ASCT-1 operates in a similar mechanism as ASCT-2.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + +
+ + + +

References: Sareen S. Gropper, jack L. Smith, James L. Groff (2009) Wadaworth cengage learning, Advanced nutrition and human metabolism, 5th edition, page 143-144. charasuraisin, c. in short dissertation 19 (2008)

+

Confidence Level: 0.0

+

NOTES: re-formation of cholesterol ester within enterocytes, then exit in chylomicrons into the lymph.

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: newly synthesized cholesterol may either be incorporated into membrane or transported out of enterocytes.

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

References: added during gap filling.

+

Confidence Level: 0.0

+

NOTES: added during gap filling.

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

References: Davidson, N. O Magun, A. M. and Glickman, R. M. 2011. Enterocyte Lipid Absorption and Secretion. Comprehensive Physiology. 505?526, .

+

Confidence Level: 0.0

+

NOTES: Enterocytes stand next to liver in endogenous cholesterol synthesis. in rats they provide 25% of bodys cholesterol. the crypt epithelial cells synthesize maximum cholesterol when compared to other parts of the GI tract (PMCID: PMC292609). Reactions till farnesyl pyrophosphate operates in cytosol, however, further steps including squalene synthase operates in E.R (Harpers illustrated Biochemistry (2009) 28th edition, Lange medical publications, chapter 26, page 224-227). all the cholesterol synthesis enzymes have also been found in peroxisomes (PMID: 12121718), no evidence for enterocyte sub-cellular sites, so cytosolic reactions have been added according to Harper book. one proton added t product for elemental balancing.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: Sareen S. Gropper, Jack L. Smith, James L. Groff (2009) Advanced nutrition and human metabolism, Wadsworth cengage learning, 5th edition, page 472-476.

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

References: required for cholesterol synthesis in E.R.

+

Confidence Level: 0.0

+

NOTES: required for cholesterol synthesis in E.R.

+ +
+ + + + + + +
+ + + +

References: Harpers illustrated Biochemistry (2009) 28th edition pages 174-183

+

Confidence Level: 0.0

+

NOTES: found in rats. HMP shunt reactions are cytosolic. Irreversible reaction, coefficient changed to 3

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: added during gap filling. No evidence found for such a reaction.

+

Confidence Level: 0.0

+

NOTES: added during gap filling. No evidence found for such a reaction.

+ +
+ + + + + + +
+ + + +

References: Kim E. Barrett, Mark Donowitz (2001) Gastrointestinal transport: Molecular physiology, Academic press, A harcourt science and technology company, chapter 10, pages 389-391.

+

Confidence Level: 0.0

+

NOTES: ASCT-1 transport system operates at the basolateral surface, acts as an amino acid exchanger. Preferred substrates are small neutral amino acids, however shown to have transport proline and hydroxy-proline. At acidic ph also transports aspartate and glutamate. the ASCT-1 operates in a similar mechanism as ASCT-2.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

References: Harpers illustrated Biochemistry (2009) 28th edition pages 174-183

+

Confidence Level: 0.0

+

NOTES: coefficient changed to 3

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

References: Davidson, N. O Magun, A. M. and Glickman, R. M. 2011. Enterocyte Lipid Absorption and Secretion. Comprehensive Physiology. 505?526, .

+

Confidence Level: 0.0

+

NOTES: Enterocytes stand next to liver in endogenous cholesterol synthesis. in rats they provide 25% of bodys cholesterol. the crypt epithelial cells synthesize maximum cholesterol when compared to other parts of the GI tract (PMCID: PMC292609). Reactions till farnesyl pyrophosphate operates in cytosol, however, further steps including squalene synthase operates in E.R (Harpers illustrated Biochemistry (2009) 28th edition, Lange medical publications, chapter 26, page 224-227). all the cholesterol synthesis enzymes have also been found in peroxisomes (PMID: 12121718), no evidence for enterocyte sub-cellular sites, so cytosolic reactions have been added according to Harper book.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

References: PMCID: PMC1820816.

+

Confidence Level: 0.0

+

NOTES: for regeneration of nad in peroxisomes, for providing nad to the beta oxidation

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: added during gap-filling, no evidence for such a reaction. only assumed.

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: added during gap filling. Assumption that such a reaction can exist. Mamalian peroxisome do not contain malate dehydrogenase.

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

References: Davidson, N. O Magun, A. M. and Glickman, R. M. 2011. Enterocyte Lipid Absorption and Secretion. Comprehensive Physiology. 505?526, .

+

Confidence Level: 0.0

+

NOTES: Enterocytes stand next to liver in endogenous cholesterol synthesis. in rats they provide 25% of bodys cholesterol. the crypt epithelial cells synthesize maximum cholesterol when compared to other parts of the GI tract (PMCID: PMC292609). Reactions till farnesyl pyrophosphate operates in cytosol, however, further steps including squalene synthase operates in E.R (Harpers illustrated Biochemistry (2009) 28th edition, Lange medical publications, chapter 26, page 224-227). all the cholesterol synthesis enzymes have also been found in peroxisomes (PMID: 12121718), no evidence for enterocyte sub-cellular sites, so cytosolic reactions have been added according to Harper book.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: Sareen S. Gropper, Jack L. Smith, James L. Groff (2009) Advanced nutrition and human metabolism, Wadsworth cengage learning, 5th edition, page 350.

+

Confidence Level: 0.0

+

NOTES: absorbed folate undergoes conversion to 5-methyl-THF within the enterocytes.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

References: Sareen S. Gropper, jack L. Smith, James L. Groff (2009) Wadaworth cengage learning, Advanced nutrition and human metabolism, 5th edition, page 194-196

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: Harpers illustrated Biochemistry (2009) 28th edition pages 174-183

+

Confidence Level: 0.0

+

NOTES: coefficient changed to 3

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: feline leukemia virus subgroup receptor c is responsible for heme transport into the protal blood.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: Davidson, N. O Magun, A. M. and Glickman, R. M. 2011. Enterocyte Lipid Absorption and Secretion. Comprehensive Physiology. 505?526, .

+

Confidence Level: 0.0

+

NOTES: Enterocytes stand next to liver in endogenous cholesterol synthesis. in rats they provide 25% of bodys cholesterol. the crypt epithelial cells synthesize maximum cholesterol when compared to other parts of the GI tract (PMCID: PMC292609). Reactions till farnesyl pyrophosphate operates in cytosol, however, further steps including squalene synthase operates in E.R (Harpers illustrated Biochemistry (2009) 28th edition, Lange medical publications, chapter 26, page 224-227). all the cholesterol synthesis enzymes have also been found in peroxisomes (PMID: 12121718), no evidence for enterocyte sub-cellular sites, so cytosolic reactions have been added according to Harper book. one proton added to substrate for elemental balancing.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + +
+ + + +

References: added during gap-filling.

+

Confidence Level: 0.0

+

NOTES: added during gap-filling.

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: putriscine uptake by the cells via passive diffusion, reported to be more rapid at the basolateral side.

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

References: Harpers illustrated Biochemistry (2009) 28th edition pages 174-183

+

Confidence Level: 0.0

+

NOTES: coefficient changed to 2

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: HMDB01348

+

Confidence Level: 0.0

+

NOTES: Sphingomyelins are synthesized by the transfer of phosphorylcholine from phosphatidylcholine to a ceramide in a reaction catalyzed by sphingomyelin synthase.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: HMDB01348

+

Confidence Level: 0.0

+

NOTES: Sphingomyelins are synthesized by the transfer of phosphorylcholine from phosphatidylcholine to a ceramide in a reaction catalyzed by sphingomyelin synthase.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: HMDB01348

+

Confidence Level: 0.0

+

NOTES: Sphingomyelins are synthesized by the transfer of phosphorylcholine from phosphatidylcholine to a ceramide in a reaction catalyzed by sphingomyelin synthase.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: HMDB01348

+

Confidence Level: 0.0

+

NOTES: Sphingomyelins are synthesized by the transfer of phosphorylcholine from phosphatidylcholine to a ceramide in a reaction catalyzed by sphingomyelin synthase.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: HMDB01348

+

Confidence Level: 0.0

+

NOTES: Sphingomyelins are synthesized by the transfer of phosphorylcholine from phosphatidylcholine to a ceramide in a reaction catalyzed by sphingomyelin synthase.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: HMDB01348

+

Confidence Level: 0.0

+

NOTES: Sphingomyelins are synthesized by the transfer of phosphorylcholine from phosphatidylcholine to a ceramide in a reaction catalyzed by sphingomyelin synthase.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: HMDB01348

+

Confidence Level: 0.0

+

NOTES: Sphingomyelins are synthesized by the transfer of phosphorylcholine from phosphatidylcholine to a ceramide in a reaction catalyzed by sphingomyelin synthase.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: HMDB01348

+

Confidence Level: 0.0

+

NOTES: Sphingomyelins are synthesized by the transfer of phosphorylcholine from phosphatidylcholine to a ceramide in a reaction catalyzed by sphingomyelin synthase.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: HMDB01348

+

Confidence Level: 0.0

+

NOTES: Sphingomyelins are synthesized by the transfer of phosphorylcholine from phosphatidylcholine to a ceramide in a reaction catalyzed by sphingomyelin synthase.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: HMDB01348

+

Confidence Level: 0.0

+

NOTES: Sphingomyelins are synthesized by the transfer of phosphorylcholine from phosphatidylcholine to a ceramide in a reaction catalyzed by sphingomyelin synthase.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: HMDB01348

+

Confidence Level: 0.0

+

NOTES: Sphingomyelins are synthesized by the transfer of phosphorylcholine from phosphatidylcholine to a ceramide in a reaction catalyzed by sphingomyelin synthase.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: HMDB01348

+

Confidence Level: 0.0

+

NOTES: Sphingomyelins are synthesized by the transfer of phosphorylcholine from phosphatidylcholine to a ceramide in a reaction catalyzed by sphingomyelin synthase.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: HMDB01348

+

Confidence Level: 0.0

+

NOTES: Sphingomyelins are synthesized by the transfer of phosphorylcholine from phosphatidylcholine to a ceramide in a reaction catalyzed by sphingomyelin synthase.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: HMDB01348

+

Confidence Level: 0.0

+

NOTES: Sphingomyelins are synthesized by the transfer of phosphorylcholine from phosphatidylcholine to a ceramide in a reaction catalyzed by sphingomyelin synthase.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: HMDB01348

+

Confidence Level: 0.0

+

NOTES: Sphingomyelins are synthesized by the transfer of phosphorylcholine from phosphatidylcholine to a ceramide in a reaction catalyzed by sphingomyelin synthase.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: HMDB01348

+

Confidence Level: 0.0

+

NOTES: Sphingomyelins are synthesized by the transfer of phosphorylcholine from phosphatidylcholine to a ceramide in a reaction catalyzed by sphingomyelin synthase.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Hepatic cholesterol esterifying and cholesterol ester hydrolysing enzymes were characterized long ago in the rat [40]. This enzyme has maximal hydrolysing activity at pH 4.5-5.0, with some tailing to neutral pH. The hydrolase requires no co-factors, is stimulated by low concentrations of the surfactant Triton X-100, and is inhibited by sulfhydryl-blocking agents [21]. Stokke subsequently established that this acid cholesterol ester hydrolase (CEH) is of lysosomal origin in the calf, and presumably also in man [22].

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Hydrolysis of phosphatidylethanolamine by human pancreatic phospholipase A2.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Phosphatidylinositol hydrolysis by phospholipase A2 and C activities in human peripheral blood neutrophils.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Hydrolysis of phosphatidylethanolamine by human pancreatic phospholipase A2.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Hydrolysis of phosphatidylethanolamine by human pancreatic phospholipase A2.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Hydrolysis of phosphatidylethanolamine by human pancreatic phospholipase A2.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Hydrolysis of phosphatidylethanolamine by human pancreatic phospholipase A2.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Hydrolysis of phosphatidylethanolamine by human pancreatic phospholipase A2.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Hydrolysis of phosphatidylethanolamine by human pancreatic phospholipase A2.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Hydrolysis of phosphatidylethanolamine by human pancreatic phospholipase A2.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Hydrolysis of phosphatidylethanolamine by human pancreatic phospholipase A2.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Hydrolysis of phosphatidylethanolamine by human pancreatic phospholipase A2.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Hydrolysis of phosphatidylethanolamine by human pancreatic phospholipase A2.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Hydrolysis of phosphatidylethanolamine by human pancreatic phospholipase A2.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Hydrolysis of phosphatidylethanolamine by human pancreatic phospholipase A2.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Phosphatidylinositol hydrolysis by phospholipase A2 and C activities in human peripheral blood neutrophils.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lysophopshatidyl-choline (LPC) is derived from polar surface phosphatidylcholine (PC) of lipoproteins or from cell membrane-derived PC as a result of phospholipase A2 (PLA2) [8,9]. There is also a phospholipase A1 (PLA1), which is able to cleave the sn-1 ester bond [10]. Appreciable amounts of LPC are either formed in plasma by endothelial lipase [10] or by lecithin-cholesterol acyltransferase (LCAT) secreted from the liver to catalyse the transfer of fatty acids, preferentially linoleate which is in sn-2 position of phosphatidylcholine, to free cholesterol in plasma for the formation of cholesteryl esters [11]. Lysophospholipase substrates the reaction of LPC and water to carboxylate and glycerophosphocholine which is further converted to sn-glycerol-3-phosphate and choline by glycerophosphocholine phosphodiesterase. Glycerol-3-phosphate acyltransferase, located in both endoplasmic reticulum and mitochondrial, catalyses the formation of the lysoproduct LPA by the acylation of glycerol 3-phosphate. LPA may also be synthesized by PLA2 catalysed deacylation of phosphatidic acid (PA). PA is generated by the hydrolysis of PC by PC-specific phospholipase D (PLD) or the acylation of LPA by LPA acyl transferases. PA is an important metabolite involved in phospholipid biosynthesis and membrane remodeling. GPR association taken from Recon.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Hydrolysis of phosphatidylethanolamine by human pancreatic phospholipase A2.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: It seems likely that glycerol 1:2-cyclic phosphate has not previously been reported as a metabolic product of glycerylphosphorylcholine and glycerylphosphorylethanolamine decomposition because of its extreme acid-lability. This means that it is quickly hydrolysed in acid protein-denaturing agents, such as trichloroacetic acid. In addition, we have established that in tissues there is an Mg2+-dependent phosphodiesterase that can rapidly open the ring and produce glycerophosphate.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: sodium symport of acylcarnitine

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: It seems likely that glycerol 1:2-cyclic phosphate has not previously been reported as a metabolic product of glycerylphosphorylcholine and glycerylphosphorylethanolamine decomposition because of its extreme acid-lability. This means that it is quickly hydrolysed in acid protein-denaturing agents, such as trichloroacetic acid. In addition, we have established that in tissues there is an Mg2+-dependent phosphodiesterase that can rapidly open the ring and produce glycerophosphate.

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: acylarnitine transport by sodium symport

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: If these effects were truly competitive then 3-methylhistidine may be transferred across cell membranes by carrier(s) responsible for glutamine, asparagine and histidine transfer (system N) and/or systems L and ASC. If transport is via the glutamine carrier then the interference by leucine (a system L substrate) and cysteine (a typical ASC substrate) could be non-competitive as occurs in the case of the uptake of glutamine itself (Hundal et al. 1987).

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: If these effects were truly competitive then 3-methylhistidine may be transferred across cell membranes by carrier(s) responsible for glutamine, asparagine and histidine transfer (system N) and/or systems L and ASC. If transport is via the glutamine carrier then the interference by leucine (a system L substrate) and cysteine (a typical ASC substrate) could be non-competitive as occurs in the case of the uptake of glutamine itself (Hundal et al. 1987).

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: If these effects were truly competitive then 3-methylhistidine may be transferred across cell membranes by carrier(s) responsible for glutamine, asparagine and histidine transfer (system N) and/or systems L and ASC. If transport is via the glutamine carrier then the interference by leucine (a system L substrate) and cysteine (a typical ASC substrate) could be non-competitive as occurs in the case of the uptake of glutamine itself (Hundal et al. 1987).

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: no evidence for such reaction,diffusion is assumed.

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: no evidence for such reaction, diffusion assumed.

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: no evidence for such reaction, transport mechanism similar to L-carnitine is assumed.

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: no evidence for such reaction, transport mechanism similar to L-carnitine is assumed.

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: no evidence for such reaction, transport mechanism similar to thymine is assumed.

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: no evidence for such reaction,diffusion is assumed.

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: pentose sugar, same as ribose

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: pentose sugar, same as ribose

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: no evidence for such reaction,diffusion is assumed.

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: no evidence for such reaction,diffusion is assumed.

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: no evidence for such reaction,diffusion is assumed.

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: no evidence for such reaction,diffusion is assumed.

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Energy involved in long chain fatty acid efflux. We surmised that E. coli already possesses the ability to secrete FFA via native drug efflux pumps or other transport machinery and sought to identify the genes responsible in this study such that they could be overexpressed to allow improved production of FFA.

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Energy required for efflux of long chain fatty acids. We surmised that E. coli already possesses the ability to secrete FFA via native drug efflux pumps or other transport machinery and sought to identify the genes responsible in this study such that they could be overexpressed to allow improved production of FFA.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: no evidence for such reaction,diffusion is assumed.

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: The transport of leukotriene C4 (LTC4) in membrane vesicles prepared from KCP-4 cells was facilitated by an ATP-dependent pump that appeared very similar to the GS-X pump. Transport mechanism similar to LTC4 is assumed.

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: ABC transport for very long chain fatty acids

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+

NOTES: no evidence for such reaction,diffusion is assumed.

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Glycolic acid (or hydroxyacetic acid) is the smallest alpha-hydroxy acid (AHA). In its pure form, glycolic acid is a colorless crystalline solid. Due to its excellent capability to penetrate skin, glycolic acid finds applications in skin care products, most often as a chemical peel. Glycolic acid is also used for tattoo removal. (HMDB00115). No evidence for such reaction, diffusion is assumed.

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Competitive inhibition of malonate uptake by eosin and inorganic anions, strongly implies that a common route exists for both inorganic anions and organic dianions, namely the anion-exchange Band 3 protein. 14C-Malonate which is nonmetabolized in the erythrocyte, could be a useful probe for monitoring anion-exchange in reconstituted Band 3 systems.

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Competitive inhibition of malonate uptake by eosin and inorganic anions, strongly implies that a common route exists for both inorganic anions and organic dianions, namely the anion-exchange Band 3 protein. 14C-Malonate which is nonmetabolized in the erythrocyte, could be a useful probe for monitoring anion-exchange in reconstituted Band 3 systems.

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: In agreement with these observations, brain mitochondrial swelling experiments indicate that MMA is an important inhibitor of succinate transport by the dicarboxylate carrier.

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: In agreement with these observations, brain mitochondrial swelling experiments indicate that MMA is an important inhibitor of succinate transport by the dicarboxylate carrier.

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: In agreement with these observations, brain mitochondrial swelling experiments indicate that MMA is an important inhibitor of succinate transport by the dicarboxylate carrier.

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: In agreement with these observations, brain mitochondrial swelling experiments indicate that MMA is an important inhibitor of succinate transport by the dicarboxylate carrier.

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: acylarnitine transport by diffusion

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: The transport of leukotriene C4 (LTC4) in membrane vesicles prepared from KCP-4 cells was facilitated by an ATP-dependent pump that appeared very similar to the GS-X pump. Transport mechanism similar to LTC4 is assumed.

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: The transport of leukotriene C4 (LTC4) in membrane vesicles prepared from KCP-4 cells was facilitated by an ATP-dependent pump that appeared very similar to the GS-X pump. Transport mechanism similar to LTC4 is assumed.

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+

NOTES: transport of long chain fatty acids by diffusion

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: no evidence for such reaction, diffusion is assumed.

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: curation of Harvey. Addition of new rxns to Recon for enabling accurate whole-body physiology. Genes/proteins for the metabolic reactions occurance in the respective organ come from Human proteome data by Kim et al. Corresponding metabolites needed to be mentioned with transport reactions.

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: curation of Harvey. Addition of new rxns to Recon for enabling accurate whole-body physiology. Genes/proteins for the metabolic reactions occurance in the respective organ come from Human proteome data by Kim et al. Corresponding metabolites needed to be mentioned with transport reactions.

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: curation of Harvey. Addition of new rxns to Recon for enabling accurate whole-body physiology. Genes/proteins for the metabolic reactions occurance in the respective organ come from Human proteome data by Kim et al. Corresponding metabolites needed to be mentioned with transport reactions.

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: curation of Harvey. Addition of new rxns to Recon for enabling accurate whole-body physiology. Genes/proteins for the metabolic reactions occurance in the respective organ come from Human proteome data by Kim et al. Corresponding metabolites needed to be mentioned with transport reactions.

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

References: HMDB00115

+

Confidence Level: 0.0

+

NOTES: Glycolic acid (or hydroxyacetic acid) is the smallest alpha-hydroxy acid (AHA). In its pure form, glycolic acid is a colorless crystalline solid. Due to its excellent capability to penetrate skin, glycolic acid finds applications in skin care products, most often as a chemical peel. Glycolic acid is also used for tattoo removal.

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Phenylethylamine produces tyramine via alterantive dopamine biosysnthesis pathway

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Tyramine produces dopamine via alterantive dopamine biosynthesis pathway, via CYP2D catalysis

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Added during debugging the metabolomic data sets, to enable their uptake by kidney and flux consistency in blood circulation.

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Added during debugging the metabolomic data sets, to enable their uptake by kidney and flux consistency in blood circulation.

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Added during debugging the metabolomic data sets, to enable their uptake by kidney and flux consistency in blood circulation.

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Added during debugging the metabolomic data sets, to enable their uptake by kidney and flux consistency in blood circulation.

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Added during debugging the metabolomic data sets, to enable their uptake by kidney and flux consistency in blood circulation.

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Added during debugging the metabolomic data sets, to enable their uptake by kidney and flux consistency in blood circulation.

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Added during debugging the metabolomic data sets, to enable their uptake by kidney only, and not other organs.

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Added during debugging the metabolomic data sets, to enable their uptake by kidney only, and not other organs.

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Added during debugging the metabolomic data sets, to enable their uptake by kidney only, and not other organs.

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Added during debugging the metabolomic data sets, to enable their uptake by kidney only, and not other organs.

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Added during debugging the metabolomic data sets, to enable their uptake by kidney only, and not other organs.

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Added during debugging the metabolomic data sets, to enable their uptake by kidney only, and not other organs.

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: No evidence found for such reaction, added for resolving deadend

+ +
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+

NOTES: taken from adipocyte model

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: taken from adipocyte model

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: taken from adipocyte model

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: taken from adipocyte model

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: taken from adipocyte model

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: taken from adipocyte model

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: taken from adipocyte model

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: taken from adipocyte model

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: taken from adipocyte model

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: taken from RBC model

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: taken from RBC model

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: taken from RBC model

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: taken from RBC model

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: taken from RBC model

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: taken from RBC model

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: taken from RBC model

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Systematic prediction of health-relevant human-microbial co-metabolism through a computational framework

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Systematic prediction of health-relevant human-microbial co-metabolism through a computational framework

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Systematic prediction of health-relevant human-microbial co-metabolism through a computational framework

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR- reversible form of ACACT1

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: originally named AACTP NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SMP. Biochemical

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: r0277

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: tv renamed from CO2TPr to CO2t NCD

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: r0608, JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Human Y/N: Y

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SMP

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+

NOTES: 6765112 - fluorescence of presence in human brain

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SMP

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: taken from RBC model

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Human Y/N: Y

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: EC 2.5.1.- NCD

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Needed in L-proline biosynthesis

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR - a reversible reaction that is otherwise identical to ZWF

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Human Y/N: Y

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SMP. Same reaction as GAPDH, but localied to spermatids. NOTE: I think "glyceroyl" in this and many other reactions should be "glycerol There are "glyceroyl" compounds, but I don't think that is what is intended here.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: BRENDA also lists beta-Ala-His dipeptidase (E.C. 3.4.13.20) as another enzyme catalyzing this reaction, but no literature evidence found.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: most probable reaction. added during gap filling.

+

Confidence Level: 0.0

+

NOTES: most probable reaction. added during gap filling.

+ +
+ + + + + + + + +
+ + + +

References: Rubino A, Pierro M, Torretta GL, Vetrella M, Martino DD, Auricch S. (1969). Pediatric Research 3: 313-9

+

Confidence Level: 0.0

+

NOTES: prolidase 1 and 2 both have same E.C. Numbers, prolidase 1 has a substrate preference for glycylproline where as prolidase 2 catalyzes very slowly this reaction (PMID: 14580160).

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Human Y/N: Y

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Guanine and 6-mercaptopurine can replace hypoxanthine EC added (2.4.2.7 makes the same reaction) IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: tv

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: _2.6.1.42

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Human Y/N: Y

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Human Y/N: Y

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Wide specificity for 5'-nucleotides Also see EC 3.1.3.31

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: tv renamed from O2TP to O2t to avoid confusion with transport reaction from cytosol to peroxisome NCD

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SMP Net reaction same as described in Lehringer 334

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SMP

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: taken from adipocyte model

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Specificity not completely determined. Can also catalyse ribosyltransferase reactions of the type catalysed by EC 2.4.2.5, nucleoside ribosyltransferase

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Specificity not completely determined. Can also catalyse ribosyltransferase reactions of the type catalysed by EC 2.4.2.5, nucleoside ribosyltransferase

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Specificity not completely determined. Can also catalyse ribosyltransferase reactions of the type catalysed by EC 2.4.2.5, nucleoside ribosyltransferase

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Specificity not completely determined. Can also catalyse ribosyltransferase reactions of the type catalysed by EC 2.4.2.5, nucleoside ribosyltransferase

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Specificity not completely determined. Can also catalyse ribosyltransferase reactions of the type catalysed by EC 2.4.2.5, nucleoside ribosyltransferase

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Specificity not completely determined. Can also catalyse ribosyltransferase reactions of the type catalysed by EC 2.4.2.5, nucleoside ribosyltransferase

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Specificity not completely determined. Can also catalyse ribosyltransferase reactions of the type catalysed by EC 2.4.2.5, nucleoside ribosyltransferasextsn

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SMP

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SMP

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SMP

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SMP Two reactions for transketolase: TKT1 and TKT2

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SMP Two reactions for transketolase: TKT1 and TKT2

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SMP. 18840520 - expression data; 18456264 - protein purification; 2579079 - genetic, homology; 999837 - biochemical

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: used yeast system to overexpress gene to determine mutant kinetic properties

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Acts on a number of porphyrinogens, r0606

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: taken from adipocyte model

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Wide specificity for 5'-nucleotides Also see EC 3.1.3.31

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Wide specificity for 5'-nucleotides Also see EC 3.1.3.31

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Wide specificity for 5'-nucleotides Also see EC 3.1.3.31. Not clear whether it is cytosolic but enzymes in this metabolism often are

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Wide specificity for 5'-nucleotides Also see EC 3.1.3.31

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Wide specificity for 5'-nucleotides Also see EC 3.1.3.31

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Wide specificity for 5'-nucleotides Also see EC 3.1.3.31

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Wide specificity for 5'-nucleotides Also see EC 3.1.3.31

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Wide specificity for 5'-nucleotides Also see EC 3.1.3.31. Rat

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Wide specificity for 5'-nucleotides Also see EC 3.1.3.31

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+

NOTES: taken from adipocyte model

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Reaction from KEGG: an acylphosphate + H2O -> a carboxylate + phosphate

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: acetylglucosamine phosphate deacetylase; acetylaminodeoxyglucosephosphate acetylhydrolase; 2-acetamido-2-deoxy-D-glucose-6-phosphate amidohydrolase

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Only acetaldehyde considered for now. See also 1.2.1.4. Wide specificity, including oxidation of D-glucuronolactone to D-glucarate. Formerly EC 1.1.1.70; r0176

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR - Kegg R02705

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Previously EC 5.3.1.10

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: INVALID ECO TERM: IFH

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IF

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SMP Note no proton generation by the the reaction

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: D-Glucose, D-mannose, D-fructose, sorbitol and D-glucosamine can act as acceptors; ITP and dATP can act as donors. The liver isoenzyme has sometimes been called glucokinase. Same as 2.7.1.4

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Guanine (see GUAPRT) and 6-mercaptopurine can replace hypoxanthine

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB 2 H's on RHS are there to balance--not certain. enzymatic assay shows substrate used by aldehyde dehydrogenase in human liver

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR- added irreversible form of LCAD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Also see LDL_D

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IF

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Biochemical

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: IT

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Wide specificity for 5'-nucleotides Also see EC 3.1.3.31

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR- added proton to balance

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Previous EC number: 4.2.1.16. New EC number 4.3.1.19. Can't enter this

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: JLR

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: also EC 2.8.3.8 NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+

NOTES: SAB

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: NCD

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: The authors conclude that mMpc1 and mMpc2 are essential components of the MPC in mammalian mitochondrial. Later it was determined that transport occurs primarily with symport of proton. Our current understanding is that two proteins, mitochondrial pyruvate carriers MPC1 and MPC2, form a hetero-oligomeric complex in the IMM to facilitate pyruvate transport. This step is required for mitochondrial pyruvate oxidation and carboxylation-critical reactions in intermediary metabolism that are dysregulated in several common diseases.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: Chalmers, R. A. and A. M. Lawson (1982). Organic Acids in Man: Analytical Chemistry, Biochemistry and Diagnosis of the Organic Acidurias. London, Chapman and Hall Ltd.

+

Confidence Level: 0.0

+

NOTES: A common clinical finding in maple syrup urine disease (MSUD) is increased concentrations in plasma and urine of valine, leucine, and isoleucine and their branched chain 2-keto- and 2-hydroxy acid metabolites. This is the result of partial, intermittent, or complete loss of activity of one or more components making up the branched chain 2-ketoacid dehydrogenase (BCKD) complex. Restricted oxidative decarboxylation of 2-ketoisovaleric, 2-ketoisocaproic, and 2-keto-3-methylvaleric acids to isobutyryl-CoA, isovaleryl-CoA, and 2-methylbutyryl-CoA, respectively, causes the accumulation of these 2-keto acids, and secondarily the amino acids, in tissues and fluids. The keto acids are also reduced to 2-hydroxyisovaleric, 2-hydroxyisocaproic, and 2-hydroxy-3-methylvaleric acids (probably by a L-lactate dehydrogenase), respectively, and these are also found increased in plasma and urine.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: no evidence found for such a transport reactions, diffusion is assumed. Dectected in saliva and urine (HMDB00317).

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

References: Chalmers, R. A. and A. M. Lawson (1982). Organic Acids in Man: Analytical Chemistry, Biochemistry and Diagnosis of the Organic Acidurias. London, Chapman and Hall Ltd.

+

Confidence Level: 0.0

+

NOTES: A common clinical finding in maple syrup urine disease (MSUD) is increased concentrations in plasma and urine of valine, leucine, and isoleucine and their branched chain 2-keto- and 2-hydroxy acid metabolites. This is the result of partial, intermittent, or complete loss of activity of one or more components making up the branched chain 2-ketoacid dehydrogenase (BCKD) complex. Restricted oxidative decarboxylation of 2-ketoisovaleric, 2-ketoisocaproic, and 2-keto-3-methylvaleric acids to isobutyryl-CoA, isovaleryl-CoA, and 2-methylbutyryl-CoA, respectively, causes the accumulation of these 2-keto acids, and secondarily the amino acids, in tissues and fluids. The keto acids are also reduced to 2-hydroxyisovaleric, 2-hydroxyisocaproic, and 2-hydroxy-3-methylvaleric acids (probably by a L-lactate dehydrogenase), respectively, and these are also found increased in plasma and urine.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: no evidence found for such a transport reactions, diffusion is assumed. Dectected in blood, csf, urine, feces, saliva and urine (HMDB00407).

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+

NOTES: In propionic acidemia, due to block in propionyl-CoA carboxylase reaction, during non-ketotic periods, when propionyl-CoA accumulation still occurs, two molecules of this substrate may condense via the action of a beta-ketothiolase to form 2-methyl-3-oxovaleryl-CoA, resulting ultimately in the excretion of 2-methyl-3-hydroxy-valeric acid and 2-methyl-3-oxovaleric acids in the urine.

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: In propionic acidemia, due to block in propionyl-CoA carboxylase reaction, during non-ketotic periods, when propionyl-CoA accumulation still occurs, two molecules of this substrate may condense via the action of a beta-ketothiolase to form 2-methyl-3-oxovaleryl-CoA, resulting ultimately in the excretion of 2-methyl-3-hydroxy-valeric acid and 2-methyl-3-oxovaleric acids in the urine.

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: no evidence found for such a reaction, difussion is assumed, as detected in urine (HMDB00408).

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: In propionic acidemia, due to block in propionyl-CoA carboxylase reaction, during non-ketotic periods, when propionyl-CoA accumulation still occurs, two molecules of this substrate may condense via the action of a beta-ketothiolase to form 2-methyl-3-oxovaleryl-CoA, resulting ultimately in the excretion of 2-methyl-3-hydroxy-valeric acid and 2-methyl-3-oxovaleric acids in the urine.

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: no evidence found for such a reaction, difussion is assumed, as detected in urine (HMDB29166).

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+

NOTES: An infant with glycogen storage disease and prolonged malnourishment showed a urinary organic acid profile during an episode of fasting hypoglycaemia with inappropriate hypoketotic dicarboxylic aciduria that was indistinguishable from that reported in long-chain L-3-hydroxyacyl-CoA dehydrogenase deficiency. Although there was a striking elevation of urinary 3-hydroxydecanedioic acid, the ratios between hydroxydicarboxylic acids were consistent with values reported to be indicate of medium-chain acyl-CoA dehydrogenase deficiency. We suspect that the fasting 3-hydroxydicarboxylic aciduria was attributable to secondarily impaired enzyme activities, the consequence of malnutrition, early infancy, and/or glycogen storage disease. Caution is advised in the interpretation of urinary organic acid patterns that indicate a 3-hydroxydicarboxylic aciduria, as well as an inappropriate hypoketotic dicarboxylic aciduria, as they may represent non-specific findings.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: An infant with glycogen storage disease and prolonged malnourishment showed a urinary organic acid profile during an episode of fasting hypoglycaemia with inappropriate hypoketotic dicarboxylic aciduria that was indistinguishable from that reported in long-chain L-3-hydroxyacyl-CoA dehydrogenase deficiency. Although there was a striking elevation of urinary 3-hydroxydecanedioic acid, the ratios between hydroxydicarboxylic acids were consistent with values reported to be indicate of medium-chain acyl-CoA dehydrogenase deficiency. We suspect that the fasting 3-hydroxydicarboxylic aciduria was attributable to secondarily impaired enzyme activities, the consequence of malnutrition, early infancy, and/or glycogen storage disease. Caution is advised in the interpretation of urinary organic acid patterns that indicate a 3-hydroxydicarboxylic aciduria, as well as an inappropriate hypoketotic dicarboxylic aciduria, as they may represent non-specific findings.

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: no evidence found for such reaction, but detected in blood and urine (HMDB00350)

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: no evidence found for such reaction, but detected in blood and urine (HMDB00350)

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+

NOTES: The 3-OH-dicarboxylic acids with chain lengths longer than 10 are good substrates for ebta-oxidation

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: The 3-OH-dicarboxylic acids with chain lengths longer than 10 are good substrates for ebta-oxidation

+ +
+ + + + + + + + + +
+ + + +

References: Chalmers, R. A. and A. M. Lawson (1982). Organic Acids in Man: Analytical Chemistry, Biochemistry and Diagnosis of the Organic Acidurias. London, Chapman and Hall Ltd

+

Confidence Level: 0.0

+

NOTES: no evidence found for such reaction, but detected in blood and urine (HMDB00325)

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

References: Chalmers, R. A. and A. M. Lawson (1982). Organic Acids in Man: Analytical Chemistry, Biochemistry and Diagnosis of the Organic Acidurias. London, Chapman and Hall Ltd

+

Confidence Level: 0.0

+

NOTES: no evidence found for such reaction, but detected in blood and urine (HMDB00325)

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

References: Chalmers, R. A. and A. M. Lawson (1982). Organic Acids in Man: Analytical Chemistry, Biochemistry and Diagnosis of the Organic Acidurias. London, Chapman and Hall Ltd .

+

Confidence Level: 0.0

+

NOTES: 5-OH-hexanoic acid, found in patients urine was considered to arise from the (w-1) oxidation of accumulating hexanoic acid, and a xenobiotic origin was also considered probable.

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

References: '

+

Confidence Level: 0.0

+

NOTES: transport mechanism similar to 4-Aminobutyrate (GABA) is assumed.

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: The data also clearly demonstrate that the efficiency of Fe and Zn transfer across the epithelial barrier can be decreased by lesser phosphorylated derivatives of IPo- This effect is largely dependent on the degree of phosphorylation of inositol. Finally, the results raise the possibility that intestinal cells may take up inositol phosphate-metal complexes that require cellular metabolism before the micronutrients can be transferred across the basolateral surface to complete the process of absorption.

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: The data also clearly demonstrate that the efficiency of Fe and Zn transfer across the epithelial barrier can be decreased by lesser phosphorylated derivatives of IPo- This effect is largely dependent on the degree of phosphorylation of inositol. Finally, the results raise the possibility that intestinal cells may take up inositol phosphate-metal complexes that require cellular metabolism before the micronutrients can be transferred across the basolateral surface to complete the process of absorption.

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: OMIM:171060,

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: '

+

Confidence Level: 0.0

+

NOTES: transport mechanism similar to 4-Aminobutyrate (GABA) is assumed.

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: vescicular transport of phospholipids into the cell

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: vescicular transport of phospholipids into the cell

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: vescicular transport of phospholipids into the cell

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: When situated in a membrane, sphingolipids first of all can diffuse as monomers in four directions. If we do not take into account the motions of the entire molecule that do not result in transport, like the rotation around their longitudinal axis and the wobble (279), sphingolipids can diffuse laterally in the two-dimensional plane of the membrane

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: When situated in a membrane, sphingolipids first of all can diffuse as monomers in four directions. If we do not take into account the motions of the entire molecule that do not result in transport, like the rotation around their longitudinal axis and the wobble (279), sphingolipids can diffuse laterally in the two-dimensional plane of the membrane

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: When situated in a membrane, sphingolipids first of all can diffuse as monomers in four directions. If we do not take into account the motions of the entire molecule that do not result in transport, like the rotation around their longitudinal axis and the wobble (279), sphingolipids can diffuse laterally in the two-dimensional plane of the membrane

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: When situated in a membrane, sphingolipids first of all can diffuse as monomers in four directions. If we do not take into account the motions of the entire molecule that do not result in transport, like the rotation around their longitudinal axis and the wobble (279), sphingolipids can diffuse laterally in the two-dimensional plane of the membrane

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: When situated in a membrane, sphingolipids first of all can diffuse as monomers in four directions. If we do not take into account the motions of the entire molecule that do not result in transport, like the rotation around their longitudinal axis and the wobble (279), sphingolipids can diffuse laterally in the two-dimensional plane of the membrane

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: When situated in a membrane, sphingolipids first of all can diffuse as monomers in four directions. If we do not take into account the motions of the entire molecule that do not result in transport, like the rotation around their longitudinal axis and the wobble (279), sphingolipids can diffuse laterally in the two-dimensional plane of the membrane

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: When situated in a membrane, sphingolipids first of all can diffuse as monomers in four directions. If we do not take into account the motions of the entire molecule that do not result in transport, like the rotation around their longitudinal axis and the wobble (279), sphingolipids can diffuse laterally in the two-dimensional plane of the membrane

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: When situated in a membrane, sphingolipids first of all can diffuse as monomers in four directions. If we do not take into account the motions of the entire molecule that do not result in transport, like the rotation around their longitudinal axis and the wobble (279), sphingolipids can diffuse laterally in the two-dimensional plane of the membrane

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: When situated in a membrane, sphingolipids first of all can diffuse as monomers in four directions. If we do not take into account the motions of the entire molecule that do not result in transport, like the rotation around their longitudinal axis and the wobble (279), sphingolipids can diffuse laterally in the two-dimensional plane of the membrane

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: When situated in a membrane, sphingolipids first of all can diffuse as monomers in four directions. If we do not take into account the motions of the entire molecule that do not result in transport, like the rotation around their longitudinal axis and the wobble (279), sphingolipids can diffuse laterally in the two-dimensional plane of the membrane

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: When situated in a membrane, sphingolipids first of all can diffuse as monomers in four directions. If we do not take into account the motions of the entire molecule that do not result in transport, like the rotation around their longitudinal axis and the wobble (279), sphingolipids can diffuse laterally in the two-dimensional plane of the membrane

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: When situated in a membrane, sphingolipids first of all can diffuse as monomers in four directions. If we do not take into account the motions of the entire molecule that do not result in transport, like the rotation around their longitudinal axis and the wobble (279), sphingolipids can diffuse laterally in the two-dimensional plane of the membrane

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: When situated in a membrane, sphingolipids first of all can diffuse as monomers in four directions. If we do not take into account the motions of the entire molecule that do not result in transport, like the rotation around their longitudinal axis and the wobble (279), sphingolipids can diffuse laterally in the two-dimensional plane of the membrane

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: When situated in a membrane, sphingolipids first of all can diffuse as monomers in four directions. If we do not take into account the motions of the entire molecule that do not result in transport, like the rotation around their longitudinal axis and the wobble (279), sphingolipids can diffuse laterally in the two-dimensional plane of the membrane

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: When situated in a membrane, sphingolipids first of all can diffuse as monomers in four directions. If we do not take into account the motions of the entire molecule that do not result in transport, like the rotation around their longitudinal axis and the wobble (279), sphingolipids can diffuse laterally in the two-dimensional plane of the membrane

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: When situated in a membrane, sphingolipids first of all can diffuse as monomers in four directions. If we do not take into account the motions of the entire molecule that do not result in transport, like the rotation around their longitudinal axis and the wobble (279), sphingolipids can diffuse laterally in the two-dimensional plane of the membrane

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: When situated in a membrane, sphingolipids first of all can diffuse as monomers in four directions. If we do not take into account the motions of the entire molecule that do not result in transport, like the rotation around their longitudinal axis and the wobble (279), sphingolipids can diffuse laterally in the two-dimensional plane of the membrane

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Confidence Level: 0.0

+

NOTES: ABC transport for very long chain fatty acids

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Our studies indicate that several sex-steroid hormones are substrates for P-gp-mediated transport and are also able to induce P-gp expression at both the protein and mRNA level in vitro. Stimulation of P-gp ATPase catalytic activity by steroid hormones was also observed, suggesting physical interactions and identifying a need for further investigations to understand the in vivo effects of endogenous and synthetic steroid hormones on the expression and function of P-gp.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Radiolabeled Glucarate ([(99m)Tc]GLA) uptake is related to GLUT-5 transporter expression and transport.

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Proton symport by monocarboxylic acid transporter (MCT1). Also known as SLC16A1. (Entrez Gene ID: 6566)

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: 17502341

+

Confidence Level: 0.0

+

NOTES: Proton-coupled monocarboxylate transporter. Catalyzes the rapid transport across the plasma membrane of many monocarboxylates such as lactate, pyruvate, branched-chain oxo acids derived from leucine, valine and isoleucine, and the ketone bodies acetoacetate, beta-hydroxybutyrate and acetate.

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: The results of the present study unequivocally prove the existence of a common Na+-dependent transport mechanism for Se-Met and Met in the jejunal BBM. SeMet and Met were actively transported across the BBM by a mechanism specific for neutral amino acids.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Confidence Level: 0.0

+

NOTES: evidenced for carnitine and acetyl carnitine. evidenced in mouse colon, for carnitine, propionylcarnitine and acetylcarnitine

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: added folate transporter

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: No evidence found for such reaction, so diffusion assumed.

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: No evidence found for such reaction, so diffusion assumed.

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Two isoforms of the human ornithine carrier, ORC1 and ORC2, have been identified by overexpression of the proteins in bacteria and by study of the transport properties of the purified proteins reconstituted into liposomes. Both transport L-isomers of ornithine, lysine, arginine, and citrulline by exchange and by unidirectional mechanisms, and they are inactivated by the same inhibitors. ORC2 has a broader specificity than ORC1, and L- and D-histidine, L-homoarginine, and D-isomers of ornithine, lysine, and ornithine are all substrates. Both proteins are expressed in a wide range of human tissues, but ORC1 is the predominant form. The highest levels of expression of both isoforms are in the liver. Five mutant forms of ORC1 associated with the human disease hyperornithinemia-hyperammonemia-homocitrullinuria were also made. The mutations abolish the transport properties of the protein. In patients with hyperornithinemia-hyperammonemia-homocitrullinuria, isoform ORC2 is unmodified, and its presence compensates partially for defective ORC1. Similar transporter for perxosime is assumed.

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Two isoforms of the human ornithine carrier, ORC1 and ORC2, have been identified by overexpression of the proteins in bacteria and by study of the transport properties of the purified proteins reconstituted into liposomes. Both transport L-isomers of ornithine, lysine, arginine, and citrulline by exchange and by unidirectional mechanisms, and they are inactivated by the same inhibitors. ORC2 has a broader specificity than ORC1, and L- and D-histidine, L-homoarginine, and D-isomers of ornithine, lysine, and ornithine are all substrates. Both proteins are expressed in a wide range of human tissues, but ORC1 is the predominant form. The highest levels of expression of both isoforms are in the liver. Five mutant forms of ORC1 associated with the human disease hyperornithinemia-hyperammonemia-homocitrullinuria were also made. The mutations abolish the transport properties of the protein. In patients with hyperornithinemia-hyperammonemia-homocitrullinuria, isoform ORC2 is unmodified, and its presence compensates partially for defective ORC1. Similar transporter for extracellular space is assumed.

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Our studies indicate that several sex-steroid hormones are substrates for P-gp-mediated transport and are also able to induce P-gp expression at both the protein and mRNA level in vitro. Stimulation of P-gp ATPase catalytic activity by steroid hormones was also observed, suggesting physical interactions and identifying a need for further investigations to understand the in vivo effects of endogenous and synthetic steroid hormones on the expression and function of P-gp. Transport mechanism similar to extracellular space is assumed.

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Our studies indicate that several sex-steroid hormones are substrates for P-gp-mediated transport and are also able to induce P-gp expression at both the protein and mRNA level in vitro. Stimulation of P-gp ATPase catalytic activity by steroid hormones was also observed, suggesting physical interactions and identifying a need for further investigations to understand the in vivo effects of endogenous and synthetic steroid hormones on the expression and function of P-gp. Transport mechanism similar to extracellular space is assumed.

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lipids, retinyl palmitate, squalene and non-cholesterol sterols were measured at baseline and after 3, 4, 6, 9, 12 and 24 h postprandially in plasma, chylomicron, VLDL and VLDL bottom and, in six randomly chosen subjects, also in IDL, LDL and HDL. In the fasting samples, squalene was mainly transported in LDL and HDL, whereas in squalene-supplemented postprandium most of squalene was carried in the triglyceride-rich lipoproteins. Postprandial squalene and retinyl palmitate curves closely resembled each other. After the squalene-enriched dietary fat load, squalene was significantly increased compared to control fat loads in plasma, chylomicrons, VLDL and IDL. Squalene addition increased significantly lathosterol/campesterol ratio in chylomicrons and VLDL at 12 h and in VLDL bottom at 9-12 h, and increased significantly VLDL lanosterol/campesterol ratio at 12 h, indicating enhanced cholesterol synthesis caused by squalene. Plasma plant sterol levels remained unchanged. In conclusion, a single oral dose of squalene representing a potential daily dietary amount increases cholesterol synthesis within 9-12 h detected in chylomicrons, VLDL and VLDL bottom.

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Lipids, retinyl palmitate, squalene and non-cholesterol sterols were measured at baseline and after 3, 4, 6, 9, 12 and 24 h postprandially in plasma, chylomicron, VLDL and VLDL bottom and, in six randomly chosen subjects, also in IDL, LDL and HDL. In the fasting samples, squalene was mainly transported in LDL and HDL, whereas in squalene-supplemented postprandium most of squalene was carried in the triglyceride-rich lipoproteins. Postprandial squalene and retinyl palmitate curves closely resembled each other. After the squalene-enriched dietary fat load, squalene was significantly increased compared to control fat loads in plasma, chylomicrons, VLDL and IDL. Squalene addition increased significantly lathosterol/campesterol ratio in chylomicrons and VLDL at 12 h and in VLDL bottom at 9-12 h, and increased significantly VLDL lanosterol/campesterol ratio at 12 h, indicating enhanced cholesterol synthesis caused by squalene. Plasma plant sterol levels remained unchanged. In conclusion, a single oral dose of squalene representing a potential daily dietary amount increases cholesterol synthesis within 9-12 h detected in chylomicrons, VLDL and VLDL bottom.

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+

NOTES: No evidence found for such reaction, so diffusion assumed.

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+

NOTES: evidence in hepatocytes (basolateral membrane), passive excretion into urine of the fraction that is not excreted into bile

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+

NOTES: possible for acylcarnitine in various tissues

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: no evidence found for specific transporter

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+

NOTES: no evidence found for specific transporter

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Dopamine and its metabolites can undergo O-glucuronides before excretion. O-glucuronides occur in both CNS and periphery. Dopamine-4-O-glucuronide and Dopamine-3-O-glucuronide are formed in almost equal amounts. Glucuronidation is performed by ER-bound uridine diphosphoglucoronosyltransferases (UGTS)

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Dopamine and its metabolites can undergo O-glucuronides before excretion. O-glucuronides occur in both CNS and periphery. Dopamine-4-O-glucuronide and Dopamine-3-O-glucuronide are formed in almost equal amounts. Glucuronidation is performed by ER-bound uridine diphosphoglucoronosyltransferases (UGTS)

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: dopamine glucuronides were found in the CSF

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Dopamine glucuronides were found in the CSF. MRP1 can transport glucuronide conjugates

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Comound was found in CSF, so it needs to be secreted. Gsh conjugate is transported out the cells and hydrolyzed by ggt and dipeptidases to the corresponding cys-dopamine. RLIP76 (10928) can catalyze transport of glutathione conjugates. RLIP76 is a multifunctional protein important for utilizing the energy currency adenosine triphosphate to transport various chemical materials outside

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: ;UNIPROT:Q8WTS1;UNIPROT:Q99943

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: UNIPROT:Q9Y6K0

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: UNIPROT:Q15125

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: ;PMID:;

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: 13295248

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

References: ;PMID:

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: ;UNIPROT:P06132

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

References: ;PMID:

+

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Confidence Level: 0.0

+

NOTES: OATP2B1 is more significant for intestinal uptake of rosuvastatin, fluvastatin ; pravastatin. Atorvastatin, cerivastatin ; pitavastatin undergo more often passive diffusion. The intestinal permeability of atorvastatin is high at the physiologically relevant intestinal luminal pH of 6-6.5 ; predicts complete absoprtion (PMID: 14531725).

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: precise transporter has not been identified for heptic uptake. In rats sodium independant uptake is seen. In humans OATP1B1 ; OATP1B3 do not mediate ibuprofen uptake, however, these NSAIDs may influence allosterically the uptake of antibiotics ; statins. OAT1 transporter mediates ibuprofen uptake at the basolateral surface in renal epithelial cells (PMID: 18309312), dectected weakly in liver as well (PMID: 10462545). OAT1 transporter is an antiporter mediating uptake of organic anion (drugs) ; efflux of dicarboxylate ion (uric acid) (PMID: 12883891).

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +

Confidence Level: 0.0

+

NOTES: precise transporter has not been identified for heptic uptake. In rats sodium independant uptake is seen. In humans OATP1B1 ; OATP1B3 do not mediate ibuprofen uptake, however, these NSAIDs may influence allosterically the uptake of antibiotics ; statins. OAT1 transporter mediates ibuprofen uptake at the basolateral surface in renal epithelial cells (PMID: 18309312), dectected weakly in liver as well (PMID: 10462545). OAT1 transporter is an antiporter mediating uptake of organic anion (drugs) ; efflux of dicarboxylate ion (uric acid) (PMID: 12883891).

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +

Confidence Level: 0.0

+

NOTES: diffusion reaction assumed due to lack of specific transport protein

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Losartan, an antagonist of the angiotensin II receptor (AT1-RA), ; its metabolite (EXP-3174) cis inhibited urate uptake ; the IC50 of losartan tended to be the same as that of probenecid consistent with the uricosuric property of losartan. URAT1 (GeneID:116085) is expresed in the renal cells ; losartan ; its active metabolite losartan-1374 was found to be its substrate, mediating antiport with organic anions (preferable chloride, can be substituted with bromide ; iodide).

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: diffusion reaction assumed due to lack of specific transport protein

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Losartan, an antagonist of the angiotensin II receptor (AT1-RA), ; its metabolite (EXP-3174) cis inhibited urate uptake ; the IC50 of losartan tended to be the same as that of probenecid consistent with the uricosuric property of losartan. URAT1 (GeneID:116085) is expresed in the renal cells ; losartan ; its active metabolite losartan-1374 was found to be its substrate, mediating antiport with organic anions (preferable chloride, can be substituted with bromide ; iodide).

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: Losartan, an antagonist of the angiotensin II receptor (AT1-RA), ; its metabolite (EXP-3174) cis inhibited urate uptake ; the IC50 of losartan tended to be the same as that of probenecid consistent with the uricosuric property of losartan. URAT1 (GeneID:116085) is expresed in the renal cells ; losartan ; its active metabolite losartan-1374 was found to be its substrate, mediating antiport with organic anions (preferable chloride, can be substituted with bromide ; iodide).

+ +
+ + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: diffusion reaction has been assumed since no conclusive evidence of a specific transport protein exists. Pgp has been shown to act as an efflux transporter in CaCo2 cells for losartan alone but not for its active metabolite losartan-1374. No PEPT1-specific uptake of valsartan ; losartan was found in HeLa cells.

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: a fraction of the intact drug passes through the small intestine at the proximal region, probably via a proton soupled carrier mediated transport, identity of the transport protein remains unknown.

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+

NOTES: transporter not identified, based on physiological evidence

+ +
+ + + + + + + + + + + + + + + + + +
+ + + +

References: Russel, F. G. M. (2010). Transporters: Importance in Drug Absorption, Distribution, ; Removal, Enzyme- ; Transporter-Based Drug-Drug Interactions. K. S. Pang, A. D. Rodrigues ; R. M. Peter, Springer New York: 27-49

+

Confidence Level: 0.0

+

NOTES: antiport transport for uptake of torasemide has been assumed, since, OATP1B1 mediates hepatic uptake of torasemide in an antipor manner, in exchange of bicarbonate.

+ +
+ + + + + + + + +
+ + + +

References: Russel, F. G. M. (2010). Transporters: Importance in Drug Absorption, Distribution, ; Removal, Enzyme- ; Transporter-Based Drug-Drug Interactions. K. S. Pang, A. D. Rodrigues ; R. M. Peter, Springer New York: 27-49, .

+

Confidence Level: 0.0

+

NOTES: In healthy volunteers ; patients with normal renal function, approximately 20% of a dose of torasemide is eliminated unchanged in the urine. The high renal clearance of torasemide indicates that the major part of torasemide is secreted by the proximal tubular anion carrier system. Hence, organic anion antiport mechanism has been assumed for hepatocytes. OAT4 located in the kidney, exchanges organic anions (efflux) for chloride (uptake). In another study, authors found that large variation in the renal clearance of torsemide, which was partially explained by genetic variation in the luminally expressed OAT4 rather than by polymorphisms in the genes coding for basolaterally located OAT1 ; OAT3.

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + + +
+ + + +

Confidence Level: 0.0

+ +
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
diff --git a/tests/unit/test_fisher_stats.py b/tests/unit/test_fisher_stats.py new file mode 100644 index 00000000..34140eb7 --- /dev/null +++ b/tests/unit/test_fisher_stats.py @@ -0,0 +1,16 @@ +import cobra +import numpy as np +from como.stats.fisher_exact_test import FisherExactTest + + +def test_fisher_stats(): + reference_model = cobra.io.load_matlab_model("main/data/reference_models/GeneralModelUpdatedV3.mat") + scenario_model = cobra.io.read_sbml_model("tests/inputs/naiveB_model.xml") + real = FisherExactTest.run(reference=reference_model, scenario=scenario_model, pathway="Glycolysis/gluconeogenesis") + + assert real.statistic == np.float64(4.321708185053381) + assert real.pvalue == np.float64(1.2883495211648955e-05) + assert real.a == 32 + assert real.b == 10 + assert real.c == 4496 + assert real.d == 6082 From 371a0ade77abd6722b9bdc5ec6933e5b6c574572 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Wed, 1 Oct 2025 15:48:51 -0500 Subject: [PATCH 248/265] refactor: rename variables for better understanding Signed-off-by: Josh Loecker --- main/como/create_context_specific_model.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 0a50890b..865c0170 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -210,13 +210,12 @@ def _build_with_fastcore(cobra_model, s_matrix, lower_bounds, upper_bounds, exp_ def _build_with_imat( - cobra_model: cobra.Model, - s_matrix: npt.NDArray, + reference_model: cobra.Model, lower_bounds: Sequence[float], upper_bounds: Sequence[float], expr_vector: npt.NDArray, expr_thresh: tuple[float, float], - force_gene_ids: Sequence[int], + force_gene_indices: Sequence[int], solver: str, ) -> (cobra.Model, pd.DataFrame): expr_vector = np.array(expr_vector) From 5419d956135db933af1beb3a2623b1797d0fa2d9 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Wed, 1 Oct 2025 15:49:36 -0500 Subject: [PATCH 249/265] refactor: only return a `cobra.Model` reconstruction Signed-off-by: Josh Loecker --- main/como/create_context_specific_model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 865c0170..08d91265 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -217,9 +217,9 @@ def _build_with_imat( expr_thresh: tuple[float, float], force_gene_indices: Sequence[int], solver: str, -) -> (cobra.Model, pd.DataFrame): expr_vector = np.array(expr_vector) properties = IMATProperties( +) -> cobra.Model: exp_vector=expr_vector, exp_thresholds=expr_thresh, core=force_gene_ids, From b5cea99d559a8d8c29106493b6e9c760b38c9680 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Thu, 2 Oct 2025 09:51:10 -0500 Subject: [PATCH 250/265] refactor: add comments stating purpose of code blocks Signed-off-by: Josh Loecker --- main/como/create_context_specific_model.py | 45 +++++++++++++--------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 08d91265..1752de2f 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -217,32 +217,39 @@ def _build_with_imat( expr_thresh: tuple[float, float], force_gene_indices: Sequence[int], solver: str, - expr_vector = np.array(expr_vector) - properties = IMATProperties( ) -> cobra.Model: + properties: IMATProperties = IMATProperties( exp_vector=expr_vector, exp_thresholds=expr_thresh, - core=force_gene_ids, + core=force_gene_indices, epsilon=0.01, solver=solver.upper(), ) - algorithm = IMAT(s_matrix, np.array(lower_bounds), np.array(upper_bounds), properties) - context_rxns: npt.NDArray = algorithm.run() - fluxes: pd.Series = algorithm.sol.to_series() - context_cobra_model = cobra_model.copy() - reaction_ids = [r.id for r in context_cobra_model.reactions] - - remove_rxns = [reaction_ids[i] for i in range(s_matrix.shape[1]) if i not in context_rxns] - flux_df = pd.DataFrame(columns=["rxn", "flux"]) - for idx, (_, val) in enumerate(fluxes.items()): - if idx <= len(cobra_model.reactions) - 1: - r_id = str(context_cobra_model.reactions.get_by_id(reaction_ids[idx])).split(":")[0] - getattr(context_cobra_model.reactions, r_id).fluxes = val - flux_df.loc[len(flux_df.index)] = [r_id, val] - - context_cobra_model.remove_reactions(remove_rxns, True) - return context_cobra_model, flux_df + # Creating a copy of the model ensures we don't make any in-place modifications by accident + # Using cobra to create the stoichiometry matrix means we have less work to do + force_gene_indices = np.array(force_gene_indices, dtype=np.uint16) + model_reconstruction: cobra.Model = reference_model.copy() + s_matrix: npt.NDArray[np.floating] = cobra.util.array.create_stoichiometric_matrix(model=model_reconstruction) + algorithm: IMAT = IMAT(S=s_matrix, lb=np.array(lower_bounds), ub=np.array(upper_bounds), properties=properties) + rxns_from_imat: npt.NDArray[np.uint16] = algorithm.run().astype(np.uint16) + + # Collect all reaction IDs and their associated index (e.g., HEX1 is at index 123) + all_rxn_ids: npt.NDArray[str] = np.array([r.id for r in model_reconstruction.reactions], dtype=object) + all_rxn_indices: npt.NDArray[np.uint16] = np.array(range(len(model_reconstruction.reactions)), dtype=np.uint16) + + # Collect reactions to keep by creating a unique set of reactions from the iMAT algorithm and force-include reactions + # dtype is set to uint16 because indices will not be below 0 or be greater than 65,535 (max size of uint16), + # because only ~10,000 reactions exist in Recon3D + # Unsafe casting is OK because of these facts. + rxn_indices_to_keep: npt.NDArray[np.uint16] = np.unique(np.concatenate([rxns_from_imat, force_gene_indices], dtype=np.uint16)) + + # Reaction indices to exclude from the model are thus reactions that are not marked to be included in the model + # Assume unique is false because every value that is in `rxn_indices_to_keep` is included in `all_rxn_indices` + rxn_indices_to_remove: npt.NDArray[np.uint16] = np.setdiff1d(all_rxn_indices, rxn_indices_to_keep, assume_unique=False) + model_reconstruction.remove_reactions(reactions=all_rxn_ids[rxn_indices_to_remove].tolist(), remove_orphans=True) + + return model_reconstruction def _build_with_tinit( From 3ea0070f58594a21077566260bcd368e7d2601d5 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Thu, 2 Oct 2025 09:52:30 -0500 Subject: [PATCH 251/265] feat: optionally force include exchange reactions Signed-off-by: Josh Loecker --- main/como/create_context_specific_model.py | 23 +++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 1752de2f..820a1960 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -367,7 +367,9 @@ async def _build_model( # noqa: C901 low_thresh: float, high_thresh: float, output_flux_result_filepath: Path, -) -> _BuildResults: + *, + force_boundary_rxn_inclusion: bool, +) -> BuildResults: """Seed a context specific reference_model. Core reactions are determined from GPR associations with gene expression logicals. @@ -389,6 +391,7 @@ async def _build_model( # noqa: C901 low_thresh: Low expression threshold for algorithms that require it (iMAT, tINIT) high_thresh: High expression threshold for algorithms that require it (iMAT, tINIT) output_flux_result_filepath: Path to save flux results (for iMAT only) + force_boundary_rxn_inclusion: If True, ensure that all boundary reactions are included in the final model. Returns: A _BuildResults object containing the context-specific model, list of expression indices used, and a DataFrame of infeasible reactions. @@ -459,8 +462,18 @@ async def _build_model( # noqa: C901 expression_vector[i] = low_thresh - 0.1 if recon_algorithm in {Algorithm.TINIT, Algorithm.IMAT} else 0 objective_index = reaction_ids.index(objective) - force_reaction_indices = [reaction_ids.index(rxn) for rxn in force_reactions if rxn in reaction_ids] - expression_vector_indices = [i for (i, val) in enumerate(expression_vector) if val > 0] # type: ignore + + if force_boundary_rxn_inclusion: + all_forced: set[str] = {*force_reactions, *boundary_reactions} + force_reaction_indices: npt.NDArray[np.uint16] = np.array( + [reaction_ids.index(rxn) for rxn in all_forced if rxn in reaction_ids], dtype=np.uint16 + ) + else: + force_reaction_indices: npt.NDArray[np.uint16] = np.array( + [reaction_ids.index(rxn) for rxn in force_reactions if rxn in reaction_ids], dtype=np.uint16 + ) + + expression_vector_indices = [i for (i, val) in enumerate(expression_vector) if val > 0] expression_threshold = (low_thresh, high_thresh) match recon_algorithm: @@ -635,6 +648,8 @@ async def create_context_specific_model( # noqa: C901 solver: Solver = Solver.GLPK, log_level: LogLevel = LogLevel.INFO, log_location: str | TextIOWrapper = sys.stderr, + *, + force_boundary_rxn_inclusion: bool = True, ): """Create a context-specific model using the provided data. @@ -657,6 +672,7 @@ async def create_context_specific_model( # noqa: C901 solver: Solver to use. One of Solver.GLPK, Solver.CPLEX, Solver.GUROBI log_level: Logging level. One of LogLevel.DEBUG, LogLevel.INFO, LogLevel.WARNING, LogLevel.ERROR, LogLevel.CRITICAL log_location: Location for log output. Can be a file path or sys.stderr/sys.stdout. + force_boundary_rxn_inclusion: If True, ensure that all provided boundary reactions are included in the final model. Raises: ImportError: If Gurobi solver is selected but gurobipy is not installed. @@ -789,6 +805,7 @@ async def create_context_specific_model( # noqa: C901 low_thresh=low_threshold, high_thresh=high_threshold, output_flux_result_filepath=output_flux_result_filepath, + force_boundary_rxn_inclusion=force_boundary_rxn_inclusion, ) build_results.infeasible_reactions.dropna(inplace=True) From b9104ae45a0e9db46a4d45f67073624d1abc288a Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Thu, 2 Oct 2025 09:52:58 -0500 Subject: [PATCH 252/265] chore: more specific type hints Signed-off-by: Josh Loecker --- main/como/create_context_specific_model.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 820a1960..72426564 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -6,9 +6,10 @@ from collections.abc import Sequence from io import TextIOWrapper from pathlib import Path -from typing import Literal, cast +from typing import Literal, TextIO, cast import cobra +import cobra.util.array import numpy as np import numpy.typing as npt import pandas as pd @@ -647,7 +648,7 @@ async def create_context_specific_model( # noqa: C901 high_threshold: float = -3, solver: Solver = Solver.GLPK, log_level: LogLevel = LogLevel.INFO, - log_location: str | TextIOWrapper = sys.stderr, + log_location: str | TextIO | TextIOWrapper = sys.stderr, *, force_boundary_rxn_inclusion: bool = True, ): From 85aee6844f0f3f24c52b592fa27223e51439e673 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Thu, 2 Oct 2025 09:53:53 -0500 Subject: [PATCH 253/265] feat(dev): make private classes public Signed-off-by: Josh Loecker --- main/como/create_context_specific_model.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 72426564..c82a5874 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -21,8 +21,8 @@ from troppo.methods.reconstruction.imat import IMAT, IMATProperties from troppo.methods.reconstruction.tINIT import tINIT, tINITProperties -from como.data_types import Algorithm, CobraCompartments, LogLevel, Solver, _BoundaryReactions, _BuildResults -from como.utils import _log_and_raise_error, _read_file, _set_up_logging, split_gene_expression_data +from como.data_types import Algorithm, BoundaryReactions, BuildResults, CobraCompartments, LogLevel, Solver +from como.utils import _log_and_raise_error, read_file, set_up_logging, split_gene_expression_data def _correct_bracket(rule: str, name: str) -> str: @@ -300,7 +300,7 @@ async def _map_expression_to_reaction( Raises: ValueError: If neither 'entrez_gene_id' nor 'ensembl_gene_id' columns are found in the gene expression file. """ - expression_data = await _read_file(gene_expression_file) + expression_data = await read_file(gene_expression_file) identifier_column = next((col for col in ("entrez_gene_id", "ensembl_gene_id") if col in expression_data.columns), "") if not identifier_column: @@ -546,7 +546,7 @@ async def _build_model( # noqa: C901 axis=0, ) - return _BuildResults( + return BuildResults( model=context_model_cobra, expression_index_list=expression_vector_indices, infeasible_reactions=inconsistent_and_infeasible_reactions, @@ -569,8 +569,8 @@ async def _create_df(path: Path) -> pd.DataFrame: return df -async def _collect_boundary_reactions(path: Path) -> _BoundaryReactions: - df: pd.DataFrame = await _create_df(path) +async def _collect_boundary_reactions(path: Path) -> BoundaryReactions: + df: pd.DataFrame = await _create_df(path, lowercase_col_names=True) for column in df.columns: if column not in [ "reaction", @@ -605,7 +605,7 @@ async def _collect_boundary_reactions(path: Path) -> _BoundaryReactions: shorthand_compartment = CobraCompartments.get_shorthand(reaction_compartment[i]) reactions[i] = f"{boundary_map.get(boundary)}_{reaction_abbreviation[i]}[{shorthand_compartment}]" - return _BoundaryReactions( + return BoundaryReactions( reactions=reactions, lower_bounds=df["minimum reaction rate"].tolist(), upper_bounds=df["maximum reaction rate"].tolist(), @@ -792,7 +792,7 @@ async def create_context_specific_model( # noqa: C901 del env, gp logger.info(f"Creating '{context_name}' model using '{algorithm.value}' reconstruction and '{solver.value}' solver") - build_results: _BuildResults = await _build_model( + build_results: BuildResults = await _build_model( general_model_file=reference_model, gene_expression_file=active_genes_filepath, recon_algorithm=algorithm, From b0479e2370de8fa15a0e36d241314c9fe3652596 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Thu, 2 Oct 2025 09:54:22 -0500 Subject: [PATCH 254/265] fix: allow .xml or .sbml model types Signed-off-by: Josh Loecker --- main/como/create_context_specific_model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index c82a5874..2d5e85d6 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -401,7 +401,7 @@ async def _build_model( # noqa: C901 match general_model_file.suffix: case ".mat": reference_model = cobra.io.load_matlab_model(general_model_file) - case ".xml": + case (".xml", ".sbml"): reference_model = cobra.io.read_sbml_model(general_model_file) case ".json": reference_model = cobra.io.load_json_model(general_model_file) From 35882d729e6893b31e50822b5516417b61c89c34 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Thu, 2 Oct 2025 10:05:22 -0500 Subject: [PATCH 255/265] style: reword log messages Signed-off-by: Josh Loecker --- main/como/create_context_specific_model.py | 48 ++++++++++++---------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 2d5e85d6..b7368adf 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -166,7 +166,15 @@ def _feasibility_test(model_cobra: cobra.Model, step: str): return incon_rxns, model_cobra_rm -def _build_with_gimme(cobra_model, s_matrix, lower_bounds, upper_bounds, idx_objective, expr_vector): +def _build_with_gimme( + reference_model: cobra.Model, + lower_bounds: Sequence[float | np.floating], + upper_bounds: Sequence[float | np.floating], + idx_objective: int, + expr_vector: npt.NDArray[np.floating], +): + model_reconstruction = reference_model.copy() + s_matrix: npt.NDArray[np.floating] = cobra.util.array.create_stoichiometric_matrix(model=model_reconstruction) # `Becker and Palsson (2008). Context-specific metabolic networks are # consistent with experiments. PLoS Comput. Biol. 4, e1000082.` properties = GIMMEProperties( @@ -178,18 +186,17 @@ def _build_with_gimme(cobra_model, s_matrix, lower_bounds, upper_bounds, idx_obj ) algorithm = GIMME(s_matrix, lower_bounds, upper_bounds, properties) gene_activity = algorithm.run() - context_cobra_model = cobra_model.copy() - reaction_ids = [r.id for r in context_cobra_model.reactions] + reaction_ids = [r.id for r in model_reconstruction.reactions] to_remove_ids = [reaction_ids[r] for r in np.where(gene_activity == 0)[0]] - context_cobra_model.remove_reactions(to_remove_ids, True) - psol = pfba(context_cobra_model) # noqa: F841 + model_reconstruction.remove_reactions(to_remove_ids, True) + psol = pfba(model_reconstruction) # noqa: F841 # reaction_ids = [r.id for r in context_cobra_model.reactions] # psol = context_cobra_model.optimize() # to_remove_ids = [reaction_ids[r] for r in np.where(abs(psol.fluxes) < 1e-8)[0]] # context_cobra_model.remove_reactions(to_remove_ids, True) - return context_cobra_model + return model_reconstruction def _build_with_fastcore(cobra_model, s_matrix, lower_bounds, upper_bounds, exp_idx_list, solver): @@ -254,8 +261,7 @@ def _build_with_imat( def _build_with_tinit( - cobra_model: cobra.Model, - s_matrix, + reference_model: cobra.Model, lower_bounds, upper_bounds, expr_vector, @@ -270,6 +276,8 @@ def _build_with_tinit( allow_excretion=False, no_reverse_loops=True, ) + model_reconstruction = reference_model.copy() + s_matrix: npt.NDArray[np.floating] = cobra.util.array.create_stoichiometric_matrix(model=model_reconstruction).astype(np.float64) algorithm = tINIT(s_matrix, lower_bounds, upper_bounds, properties) algorithm.preprocessing() algorithm.build_problem() @@ -442,8 +450,8 @@ async def _build_model( # noqa: C901 for rxn in force_reactions: if rxn not in reaction_ids: logger.warning( - f"The force reaction '{rxn}' was not found in the general reference_model. " - f"Check BiGG, or the relevant database for your general reference_model, for synonyms." + f"The force reaction '{rxn}' was not found in the reference model. " + f"Check BiGG, or the relevant database for your reference model, for synonyms." ) # collect list of reactions that are infeasible but active in expression data or user defined @@ -479,16 +487,15 @@ async def _build_model( # noqa: C901 match recon_algorithm: case Algorithm.GIMME: - context_model_cobra = _build_with_gimme( - cobra_model=reference_model, - s_matrix=s_matrix, + context_model_cobra: cobra.Model = _build_with_gimme( + reference_model=reference_model, lower_bounds=lower_bounds, upper_bounds=upper_bounds, idx_objective=objective_index, expr_vector=expression_vector, ) case Algorithm.FASTCORE: - context_model_cobra = _build_with_fastcore( + context_model_cobra: cobra.Model = _build_with_fastcore( cobra_model=reference_model, s_matrix=s_matrix, lower_bounds=lower_bounds, @@ -497,10 +504,8 @@ async def _build_model( # noqa: C901 solver=solver, ) case Algorithm.IMAT: - context_model_cobra: cobra.Model - context_model_cobra, flux_df = _build_with_imat( - cobra_model=reference_model, - s_matrix=s_matrix, + context_model_cobra: cobra.Model = _build_with_imat( + reference_model=reference_model, lower_bounds=lower_bounds, upper_bounds=upper_bounds, expr_vector=expression_vector, @@ -515,9 +520,8 @@ async def _build_model( # noqa: C901 flux_df.dropna(inplace=True) flux_df.to_csv(output_flux_result_filepath) case Algorithm.TINIT: - context_model_cobra = _build_with_tinit( - cobra_model=reference_model, - s_matrix=s_matrix, + context_model_cobra: cobra.Model = _build_with_tinit( + reference_model=reference_model, lower_bounds=lower_bounds, upper_bounds=upper_bounds, expr_vector=expression_vector, @@ -785,7 +789,7 @@ async def create_context_specific_model( # noqa: C901 env = gp.Env() if env.getParam("WLSACCESSID") == "" or env.getParam("WLSSECRET") == "": logger.critical( - "You have requested to use the Gurobi solver but license information cannot be found. " + "Gurobi solver requested, but license information cannot be found. " "COMO will continue, but it is HIGHLY unlikely the resulting model will be valid." ) # remove gurobi-related information, it is no longer required From 437e013edb8f13e1e0b6e02a5d630df745900736 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Thu, 2 Oct 2025 10:06:10 -0500 Subject: [PATCH 256/265] fix: use better variable name Signed-off-by: Josh Loecker --- main/como/create_context_specific_model.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index b7368adf..0964bd84 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -510,13 +510,15 @@ async def _build_model( # noqa: C901 upper_bounds=upper_bounds, expr_vector=expression_vector, expr_thresh=expression_threshold, - force_gene_ids=force_reaction_indices, + force_gene_indices=force_reaction_indices, solver=solver, ) - imat_reactions = flux_df.rxn - model_reactions = [reaction.id for reaction in context_model_cobra.reactions] - reaction_intersections = set(imat_reactions).intersection(model_reactions) - flux_df: pd.DataFrame = flux_df[~flux_df["rxn"].isin(reaction_intersections)] + context_model_cobra.objective = objective + flux_sol: cobra.Solution = context_model_cobra.optimize() + fluxes: pd.Series = flux_sol.fluxes + model_reactions: list[str] = [reaction.id for reaction in context_model_cobra.reactions] + reaction_intersections: set[str] = set(fluxes.index).intersection(model_reactions) + flux_df: pd.DataFrame = fluxes[~fluxes.index.isin(reaction_intersections)] flux_df.dropna(inplace=True) flux_df.to_csv(output_flux_result_filepath) case Algorithm.TINIT: From 57ced4f5d847c0a5ea5afd57229be191ca5ac5b9 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Thu, 2 Oct 2025 10:06:28 -0500 Subject: [PATCH 257/265] feat(dev): optional lowercasing of dataframe column names Signed-off-by: Josh Loecker --- main/como/create_context_specific_model.py | 27 +++++++++++----------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 0964bd84..5bc320cf 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -559,19 +559,20 @@ async def _build_model( # noqa: C901 ) -async def _create_df(path: Path) -> pd.DataFrame: - match path.suffix: - case ".csv" | ".tsv": - df = await _read_file(path, header=0, sep="," if path.suffix == ".csv" else "\t") - case ".xlsx" | ".xls": - df = await _read_file(path, header=0) - case _: - _log_and_raise_error( - f"File not found! Must be a csv, tsv, or Excel file. Searching for: {path}", - error=FileNotFoundError, - level=LogLevel.ERROR, - ) - df.columns = [c.lower() for c in df.columns] +async def _create_df(path: Path, *, lowercase_col_names: bool = False) -> pd.DataFrame: + if path.suffix not in {".csv", ".tsv"}: + raise ValueError(f"File must be a .csv or .tsv file, got '{path.suffix}'") + df: pd.DataFrame = await read_file(path=path, header=0, sep="," if path.suffix == ".csv" else "\t", h5ad_as_df=True) + + if not isinstance(df, pd.DataFrame): + _log_and_raise_error( + f"Expected a pandas.DataFrame, got {type(df)}", + error=TypeError, + level=LogLevel.ERROR, + ) + + if lowercase_col_names: + df.columns = [c.lower() for c in df.columns] return df From bff3654ae6ce52cf3b2e5d39294446e8ae6aa0c5 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Thu, 2 Oct 2025 10:06:42 -0500 Subject: [PATCH 258/265] feat(dev): fix ty warning Signed-off-by: Josh Loecker --- main/como/create_context_specific_model.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/main/como/create_context_specific_model.py b/main/como/create_context_specific_model.py index 5bc320cf..1d5b6863 100644 --- a/main/como/create_context_specific_model.py +++ b/main/como/create_context_specific_model.py @@ -597,8 +597,8 @@ async def _collect_boundary_reactions(path: Path) -> BoundaryReactions: reactions: list[str] = [""] * len(df) boundary_type: list[str] = df["reaction"].tolist() - reaction_abbreviation: list[str] = df["abbreviation"].astype(str).tolist() - reaction_compartment: list[str] = df["compartment"].astype(str).tolist() + reaction_abbreviation: list[str] = list(df["abbreviation"].astype(str)) + reaction_compartment: list[str] = list(df["compartment"].astype(str)) boundary_map = {"exchange": "EX", "demand": "DM", "sink": "SK"} for i in range(len(boundary_type)): boundary: str = boundary_type[i].lower() @@ -685,7 +685,8 @@ async def create_context_specific_model( # noqa: C901 Raises: ImportError: If Gurobi solver is selected but gurobipy is not installed. """ - _set_up_logging(level=log_level, location=log_location) + boundary_rxns_filepath: Path | None = Path(boundary_rxns_filepath) if boundary_rxns_filepath else None + set_up_logging(level=log_level, location=log_location) output_model_filepaths = [output_model_filepaths] if isinstance(output_model_filepaths, Path) else output_model_filepaths for path in output_model_filepaths: if path.suffix not in {".mat", ".xml", ".sbml", ".json"}: @@ -767,7 +768,7 @@ async def create_context_specific_model( # noqa: C901 force_rxns: list[str] = [] if force_rxns_filepath: force_rxns_filepath: Path = Path(force_rxns_filepath) - df = await _create_df(force_rxns_filepath) + df = await _create_df(force_rxns_filepath, lowercase_col_names=True) if "abbreviation" not in df.columns: _log_and_raise_error( "The force reactions file should have a single column with a header named Abbreviation", From b511c091f5d83ceea43ee66f81879eef130e22a3 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Mon, 6 Oct 2025 16:00:35 -0500 Subject: [PATCH 259/265] fix: uv lock dependencies Signed-off-by: Josh Loecker --- uv.lock | 1441 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 746 insertions(+), 695 deletions(-) diff --git a/uv.lock b/uv.lock index 8d226ed8..bcf16419 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 2 +revision = 3 requires-python = ">=3.11, <3.14" resolution-markers = [ "python_full_version >= '3.12'", @@ -17,11 +17,11 @@ wheels = [ [[package]] name = "aioftp" -version = "0.26.2" +version = "0.27.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/df/0c/9cb5a5570af3b22ad188f63d5f6166da1344c9e720cda39e5de622114473/aioftp-0.26.2.tar.gz", hash = "sha256:ecd8cc9687bbb5e1b4dddc155aa1f3ea873d6e9f9e968221378daf04c2e4f763", size = 70140, upload-time = "2025-06-27T11:22:20.449Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/a3/d1af4b69c09dc9955fdb329de5a9ea73f6a3ba50ac4861882453254ffa99/aioftp-0.27.2.tar.gz", hash = "sha256:7c048c3220081796c59832a6fd9fd8fad97e3cec12a50be3abccf2dcbbeb261a", size = 70248, upload-time = "2025-09-24T21:51:31.297Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/05/e7/4921e957802495fcd2ce39cbf7b30338dd2250d2ecd3eb9de2077aa4b8fe/aioftp-0.26.2-py3-none-any.whl", hash = "sha256:c44d1de5e4b80b23eb2f5b45871e71e36e72cd623b06cc8ab9afd32873389105", size = 44393, upload-time = "2025-06-27T11:22:19.118Z" }, + { url = "https://files.pythonhosted.org/packages/7c/6c/d56c290696f91c4f0fa4be7cfdb38e710d9735c10c57e481cd4bd6066506/aioftp-0.27.2-py3-none-any.whl", hash = "sha256:83befd4091be0e26eeba44dadebb7e7bea653f7b6bda3ba9b6785d4372a93e10", size = 44292, upload-time = "2025-09-24T21:51:29.448Z" }, ] [[package]] @@ -55,16 +55,16 @@ wheels = [ [[package]] name = "anyio" -version = "4.10.0" +version = "4.11.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "sniffio" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f1/b4/636b3b65173d3ce9a38ef5f0522789614e590dab6a8d505340a4efe4c567/anyio-4.10.0.tar.gz", hash = "sha256:3f3fae35c96039744587aa5b8371e7e8e603c0702999535961dd336026973ba6", size = 213252, upload-time = "2025-08-04T08:54:26.451Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c6/78/7d432127c41b50bccba979505f272c16cbcadcc33645d5fa3a738110ae75/anyio-4.11.0.tar.gz", hash = "sha256:82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4", size = 219094, upload-time = "2025-09-23T09:19:12.58Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6f/12/e5e0282d673bb9746bacfb6e2dba8719989d3660cdb2ea79aee9a9651afb/anyio-4.10.0-py3-none-any.whl", hash = "sha256:60e474ac86736bbfd6f210f7a61218939c318f43f9972497381f1c5e930ed3d1", size = 107213, upload-time = "2025-08-04T08:54:24.882Z" }, + { url = "https://files.pythonhosted.org/packages/15/b3/9b1a8074496371342ec1e796a96f99c82c945a339cd81a8e73de28b4cf9e/anyio-4.11.0-py3-none-any.whl", hash = "sha256:0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc", size = 109097, upload-time = "2025-09-23T09:19:10.601Z" }, ] [[package]] @@ -169,11 +169,11 @@ wheels = [ [[package]] name = "attrs" -version = "25.3.0" +version = "25.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032, upload-time = "2025-03-13T11:10:22.779Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6b/5c/685e6633917e101e5dcb62b9dd76946cbb57c26e133bae9e0cd36033c0a9/attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11", size = 934251, upload-time = "2025-10-06T13:54:44.725Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload-time = "2025-03-13T11:10:21.14Z" }, + { url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload-time = "2025-10-06T13:54:43.17Z" }, ] [[package]] @@ -187,15 +187,15 @@ wheels = [ [[package]] name = "beautifulsoup4" -version = "4.13.5" +version = "4.14.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "soupsieve" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/85/2e/3e5079847e653b1f6dc647aa24549d68c6addb4c595cc0d902d1b19308ad/beautifulsoup4-4.13.5.tar.gz", hash = "sha256:5e70131382930e7c3de33450a2f54a63d5e4b19386eab43a5b34d594268f3695", size = 622954, upload-time = "2025-08-24T14:06:13.168Z" } +sdist = { url = "https://files.pythonhosted.org/packages/77/e9/df2358efd7659577435e2177bfa69cba6c33216681af51a707193dec162a/beautifulsoup4-4.14.2.tar.gz", hash = "sha256:2a98ab9f944a11acee9cc848508ec28d9228abfd522ef0fad6a02a72e0ded69e", size = 625822, upload-time = "2025-09-29T10:05:42.613Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/04/eb/f4151e0c7377a6e08a38108609ba5cede57986802757848688aeedd1b9e8/beautifulsoup4-4.13.5-py3-none-any.whl", hash = "sha256:642085eaa22233aceadff9c69651bc51e8bf3f874fb6d7104ece2beb24b47c4a", size = 105113, upload-time = "2025-08-24T14:06:14.884Z" }, + { url = "https://files.pythonhosted.org/packages/94/fe/3aed5d0be4d404d12d36ab97e2f1791424d9ca39c2f754a6285d59a3b01d/beautifulsoup4-4.14.2-py3-none-any.whl", hash = "sha256:5ef6fa3a8cbece8488d66985560f97ed091e22bbc4e9c2338508a9d5de6d4515", size = 106392, upload-time = "2025-09-29T10:05:43.771Z" }, ] [[package]] @@ -226,56 +226,59 @@ wheels = [ [[package]] name = "certifi" -version = "2025.8.3" +version = "2025.10.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/dc/67/960ebe6bf230a96cda2e0abcf73af550ec4f090005363542f0765df162e0/certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407", size = 162386, upload-time = "2025-08-03T03:07:47.08Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4c/5b/b6ce21586237c77ce67d01dc5507039d444b630dd76611bbca2d8e5dcd91/certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43", size = 164519, upload-time = "2025-10-05T04:12:15.808Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/48/1549795ba7742c948d2ad169c1c8cdbae65bc450d6cd753d124b17c8cd32/certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5", size = 161216, upload-time = "2025-08-03T03:07:45.777Z" }, + { url = "https://files.pythonhosted.org/packages/e4/37/af0d2ef3967ac0d6113837b44a4f0bfe1328c2b9763bd5b1744520e5cfed/certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de", size = 163286, upload-time = "2025-10-05T04:12:14.03Z" }, ] [[package]] name = "cffi" -version = "1.17.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pycparser" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621, upload-time = "2024-09-04T20:45:21.852Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6b/f4/927e3a8899e52a27fa57a48607ff7dc91a9ebe97399b357b85a0c7892e00/cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401", size = 182264, upload-time = "2024-09-04T20:43:51.124Z" }, - { url = "https://files.pythonhosted.org/packages/6c/f5/6c3a8efe5f503175aaddcbea6ad0d2c96dad6f5abb205750d1b3df44ef29/cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf", size = 178651, upload-time = "2024-09-04T20:43:52.872Z" }, - { url = "https://files.pythonhosted.org/packages/94/dd/a3f0118e688d1b1a57553da23b16bdade96d2f9bcda4d32e7d2838047ff7/cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4", size = 445259, upload-time = "2024-09-04T20:43:56.123Z" }, - { url = "https://files.pythonhosted.org/packages/2e/ea/70ce63780f096e16ce8588efe039d3c4f91deb1dc01e9c73a287939c79a6/cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", size = 469200, upload-time = "2024-09-04T20:43:57.891Z" }, - { url = "https://files.pythonhosted.org/packages/1c/a0/a4fa9f4f781bda074c3ddd57a572b060fa0df7655d2a4247bbe277200146/cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", size = 477235, upload-time = "2024-09-04T20:44:00.18Z" }, - { url = "https://files.pythonhosted.org/packages/62/12/ce8710b5b8affbcdd5c6e367217c242524ad17a02fe5beec3ee339f69f85/cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", size = 459721, upload-time = "2024-09-04T20:44:01.585Z" }, - { url = "https://files.pythonhosted.org/packages/ff/6b/d45873c5e0242196f042d555526f92aa9e0c32355a1be1ff8c27f077fd37/cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", size = 467242, upload-time = "2024-09-04T20:44:03.467Z" }, - { url = "https://files.pythonhosted.org/packages/1a/52/d9a0e523a572fbccf2955f5abe883cfa8bcc570d7faeee06336fbd50c9fc/cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", size = 477999, upload-time = "2024-09-04T20:44:05.023Z" }, - { url = "https://files.pythonhosted.org/packages/44/74/f2a2460684a1a2d00ca799ad880d54652841a780c4c97b87754f660c7603/cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f", size = 454242, upload-time = "2024-09-04T20:44:06.444Z" }, - { url = "https://files.pythonhosted.org/packages/f8/4a/34599cac7dfcd888ff54e801afe06a19c17787dfd94495ab0c8d35fe99fb/cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b", size = 478604, upload-time = "2024-09-04T20:44:08.206Z" }, - { url = "https://files.pythonhosted.org/packages/34/33/e1b8a1ba29025adbdcda5fb3a36f94c03d771c1b7b12f726ff7fef2ebe36/cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655", size = 171727, upload-time = "2024-09-04T20:44:09.481Z" }, - { url = "https://files.pythonhosted.org/packages/3d/97/50228be003bb2802627d28ec0627837ac0bf35c90cf769812056f235b2d1/cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0", size = 181400, upload-time = "2024-09-04T20:44:10.873Z" }, - { url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178, upload-time = "2024-09-04T20:44:12.232Z" }, - { url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840, upload-time = "2024-09-04T20:44:13.739Z" }, - { url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803, upload-time = "2024-09-04T20:44:15.231Z" }, - { url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850, upload-time = "2024-09-04T20:44:17.188Z" }, - { url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729, upload-time = "2024-09-04T20:44:18.688Z" }, - { url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256, upload-time = "2024-09-04T20:44:20.248Z" }, - { url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424, upload-time = "2024-09-04T20:44:21.673Z" }, - { url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568, upload-time = "2024-09-04T20:44:23.245Z" }, - { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736, upload-time = "2024-09-04T20:44:24.757Z" }, - { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448, upload-time = "2024-09-04T20:44:26.208Z" }, - { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976, upload-time = "2024-09-04T20:44:27.578Z" }, - { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989, upload-time = "2024-09-04T20:44:28.956Z" }, - { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802, upload-time = "2024-09-04T20:44:30.289Z" }, - { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792, upload-time = "2024-09-04T20:44:32.01Z" }, - { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893, upload-time = "2024-09-04T20:44:33.606Z" }, - { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810, upload-time = "2024-09-04T20:44:35.191Z" }, - { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200, upload-time = "2024-09-04T20:44:36.743Z" }, - { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447, upload-time = "2024-09-04T20:44:38.492Z" }, - { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358, upload-time = "2024-09-04T20:44:40.046Z" }, - { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469, upload-time = "2024-09-04T20:44:41.616Z" }, - { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475, upload-time = "2024-09-04T20:44:43.733Z" }, - { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009, upload-time = "2024-09-04T20:44:45.309Z" }, +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycparser", marker = "implementation_name != 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload-time = "2025-09-08T23:24:04.541Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/4a/3dfd5f7850cbf0d06dc84ba9aa00db766b52ca38d8b86e3a38314d52498c/cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe", size = 184344, upload-time = "2025-09-08T23:22:26.456Z" }, + { url = "https://files.pythonhosted.org/packages/4f/8b/f0e4c441227ba756aafbe78f117485b25bb26b1c059d01f137fa6d14896b/cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c", size = 180560, upload-time = "2025-09-08T23:22:28.197Z" }, + { url = "https://files.pythonhosted.org/packages/b1/b7/1200d354378ef52ec227395d95c2576330fd22a869f7a70e88e1447eb234/cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92", size = 209613, upload-time = "2025-09-08T23:22:29.475Z" }, + { url = "https://files.pythonhosted.org/packages/b8/56/6033f5e86e8cc9bb629f0077ba71679508bdf54a9a5e112a3c0b91870332/cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93", size = 216476, upload-time = "2025-09-08T23:22:31.063Z" }, + { url = "https://files.pythonhosted.org/packages/dc/7f/55fecd70f7ece178db2f26128ec41430d8720f2d12ca97bf8f0a628207d5/cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5", size = 203374, upload-time = "2025-09-08T23:22:32.507Z" }, + { url = "https://files.pythonhosted.org/packages/84/ef/a7b77c8bdc0f77adc3b46888f1ad54be8f3b7821697a7b89126e829e676a/cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664", size = 202597, upload-time = "2025-09-08T23:22:34.132Z" }, + { url = "https://files.pythonhosted.org/packages/d7/91/500d892b2bf36529a75b77958edfcd5ad8e2ce4064ce2ecfeab2125d72d1/cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26", size = 215574, upload-time = "2025-09-08T23:22:35.443Z" }, + { url = "https://files.pythonhosted.org/packages/44/64/58f6255b62b101093d5df22dcb752596066c7e89dd725e0afaed242a61be/cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9", size = 218971, upload-time = "2025-09-08T23:22:36.805Z" }, + { url = "https://files.pythonhosted.org/packages/ab/49/fa72cebe2fd8a55fbe14956f9970fe8eb1ac59e5df042f603ef7c8ba0adc/cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414", size = 211972, upload-time = "2025-09-08T23:22:38.436Z" }, + { url = "https://files.pythonhosted.org/packages/0b/28/dd0967a76aab36731b6ebfe64dec4e981aff7e0608f60c2d46b46982607d/cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743", size = 217078, upload-time = "2025-09-08T23:22:39.776Z" }, + { url = "https://files.pythonhosted.org/packages/2b/c0/015b25184413d7ab0a410775fdb4a50fca20f5589b5dab1dbbfa3baad8ce/cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5", size = 172076, upload-time = "2025-09-08T23:22:40.95Z" }, + { url = "https://files.pythonhosted.org/packages/ae/8f/dc5531155e7070361eb1b7e4c1a9d896d0cb21c49f807a6c03fd63fc877e/cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5", size = 182820, upload-time = "2025-09-08T23:22:42.463Z" }, + { url = "https://files.pythonhosted.org/packages/95/5c/1b493356429f9aecfd56bc171285a4c4ac8697f76e9bbbbb105e537853a1/cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d", size = 177635, upload-time = "2025-09-08T23:22:43.623Z" }, + { url = "https://files.pythonhosted.org/packages/ea/47/4f61023ea636104d4f16ab488e268b93008c3d0bb76893b1b31db1f96802/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", size = 185271, upload-time = "2025-09-08T23:22:44.795Z" }, + { url = "https://files.pythonhosted.org/packages/df/a2/781b623f57358e360d62cdd7a8c681f074a71d445418a776eef0aadb4ab4/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", size = 181048, upload-time = "2025-09-08T23:22:45.938Z" }, + { url = "https://files.pythonhosted.org/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe", size = 212529, upload-time = "2025-09-08T23:22:47.349Z" }, + { url = "https://files.pythonhosted.org/packages/d5/72/12b5f8d3865bf0f87cf1404d8c374e7487dcf097a1c91c436e72e6badd83/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062", size = 220097, upload-time = "2025-09-08T23:22:48.677Z" }, + { url = "https://files.pythonhosted.org/packages/c2/95/7a135d52a50dfa7c882ab0ac17e8dc11cec9d55d2c18dda414c051c5e69e/cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e", size = 207983, upload-time = "2025-09-08T23:22:50.06Z" }, + { url = "https://files.pythonhosted.org/packages/3a/c8/15cb9ada8895957ea171c62dc78ff3e99159ee7adb13c0123c001a2546c1/cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037", size = 206519, upload-time = "2025-09-08T23:22:51.364Z" }, + { url = "https://files.pythonhosted.org/packages/78/2d/7fa73dfa841b5ac06c7b8855cfc18622132e365f5b81d02230333ff26e9e/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba", size = 219572, upload-time = "2025-09-08T23:22:52.902Z" }, + { url = "https://files.pythonhosted.org/packages/07/e0/267e57e387b4ca276b90f0434ff88b2c2241ad72b16d31836adddfd6031b/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94", size = 222963, upload-time = "2025-09-08T23:22:54.518Z" }, + { url = "https://files.pythonhosted.org/packages/b6/75/1f2747525e06f53efbd878f4d03bac5b859cbc11c633d0fb81432d98a795/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187", size = 221361, upload-time = "2025-09-08T23:22:55.867Z" }, + { url = "https://files.pythonhosted.org/packages/7b/2b/2b6435f76bfeb6bbf055596976da087377ede68df465419d192acf00c437/cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18", size = 172932, upload-time = "2025-09-08T23:22:57.188Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ed/13bd4418627013bec4ed6e54283b1959cf6db888048c7cf4b4c3b5b36002/cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5", size = 183557, upload-time = "2025-09-08T23:22:58.351Z" }, + { url = "https://files.pythonhosted.org/packages/95/31/9f7f93ad2f8eff1dbc1c3656d7ca5bfd8fb52c9d786b4dcf19b2d02217fa/cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6", size = 177762, upload-time = "2025-09-08T23:22:59.668Z" }, + { url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230, upload-time = "2025-09-08T23:23:00.879Z" }, + { url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043, upload-time = "2025-09-08T23:23:02.231Z" }, + { url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446, upload-time = "2025-09-08T23:23:03.472Z" }, + { url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101, upload-time = "2025-09-08T23:23:04.792Z" }, + { url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948, upload-time = "2025-09-08T23:23:06.127Z" }, + { url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422, upload-time = "2025-09-08T23:23:07.753Z" }, + { url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499, upload-time = "2025-09-08T23:23:09.648Z" }, + { url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928, upload-time = "2025-09-08T23:23:10.928Z" }, + { url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302, upload-time = "2025-09-08T23:23:12.42Z" }, + { url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909, upload-time = "2025-09-08T23:23:14.32Z" }, + { url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402, upload-time = "2025-09-08T23:23:15.535Z" }, + { url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780, upload-time = "2025-09-08T23:23:16.761Z" }, ] [[package]] @@ -331,15 +334,15 @@ wheels = [ [[package]] name = "choreographer" -version = "1.0.10" +version = "1.1.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "logistro" }, { name = "simplejson" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/71/0e/88c2a0307e27f40bd0ce18e66ba2c8f7327b95b23adc51ea57a08cb96797/choreographer-1.0.10.tar.gz", hash = "sha256:7adf84a0d6a6054386d5cce013fdcadb2426479e49c9b0cb06af7d3712ed263c", size = 40455, upload-time = "2025-08-22T20:37:25.461Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/20/7804e116e933231ee93b16882553677f0b3a5aa66e0a43f0ac463065bf13/choreographer-1.1.1.tar.gz", hash = "sha256:76d1c9ebd2bc23516a0adef571e318b44e198ad33babbc5faa9e92e5a9ff834f", size = 41640, upload-time = "2025-09-18T20:44:20.511Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d3/c2/82389f6e20098a414ddcf88d3b8032809b7a66e70f9bc5264f81beb24b4a/choreographer-1.0.10-py3-none-any.whl", hash = "sha256:b23ec2409f38ec89a544558eadeb19688746bab9a0f47e7115477d6e80a14a41", size = 51300, upload-time = "2025-08-22T20:37:24.372Z" }, + { url = "https://files.pythonhosted.org/packages/71/7b/63d73f4e911ad0c91dcfe53c56e2c9651d739302951f73fac216ea0477a4/choreographer-1.1.1-py3-none-any.whl", hash = "sha256:7a3d905d5a172d4a28bcff678cff8f60f85a8bc1bc59f2ed6c28150dfb9cce2c", size = 52287, upload-time = "2025-09-18T20:44:18.458Z" }, ] [[package]] @@ -398,24 +401,25 @@ wheels = [ [[package]] name = "commitizen" -version = "4.8.3" +version = "4.9.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "argcomplete" }, { name = "charset-normalizer" }, { name = "colorama" }, { name = "decli" }, - { name = "importlib-metadata" }, + { name = "deprecated" }, { name = "jinja2" }, { name = "packaging" }, + { name = "prompt-toolkit" }, { name = "pyyaml" }, { name = "questionary" }, { name = "termcolor" }, { name = "tomlkit" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ee/c0/fe5ba5555f2891bcb0b3e7dc1c57fcfd206ab7133a3094d70b81fd5a4a10/commitizen-4.8.3.tar.gz", hash = "sha256:303ebdc271217aadbb6a73a015612121291d180c8cdd05b5251c7923d4a14195", size = 56225, upload-time = "2025-06-09T14:18:51.472Z" } +sdist = { url = "https://files.pythonhosted.org/packages/77/19/927ac5b0eabb9451e2d5bb45b30813915c9a1260713b5b68eeb31358ea23/commitizen-4.9.1.tar.gz", hash = "sha256:b076b24657718f7a35b1068f2083bd39b4065d250164a1398d1dac235c51753b", size = 56610, upload-time = "2025-09-10T14:19:33.746Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/11/37/5a8e1dadd02eede38bf5a92af108071f6a11b6fc50b7ae27d9083c649ba9/commitizen-4.8.3-py3-none-any.whl", hash = "sha256:91f261387ca2bbb4ab6c79a1a6378dc1576ffb40e3b7dbee201724d95aceba38", size = 80112, upload-time = "2025-06-09T14:18:49.673Z" }, + { url = "https://files.pythonhosted.org/packages/cf/49/577035b841442fe031b017027c3d99278b46104d227f0353c69dbbe55148/commitizen-4.9.1-py3-none-any.whl", hash = "sha256:4241b2ecae97b8109af8e587c36bc3b805a09b9a311084d159098e12d6ead497", size = 80624, upload-time = "2025-09-10T14:19:32.102Z" }, ] [[package]] @@ -473,21 +477,6 @@ interactive = [ { name = "jupyterlab" }, ] -[package.dev-dependencies] -dev = [ - { name = "commitizen" }, - { name = "commitlint" }, - { name = "como" }, - { name = "pandas-stubs" }, - { name = "pre-commit" }, - { name = "pytest" }, - { name = "pytest-asyncio" }, - { name = "pytest-cov" }, - { name = "ruff" }, - { name = "scipy-stubs" }, - { name = "types-aiofiles" }, -] - [package.metadata] requires-dist = [ { name = "aioftp", specifier = ">=0.23.1" }, @@ -526,21 +515,6 @@ requires-dist = [ ] provides-extras = ["dev", "gurobi", "interactive"] -[package.metadata.requires-dev] -dev = [ - { name = "commitizen", specifier = ">=4.8.3" }, - { name = "commitlint", specifier = ">=1.3.1" }, - { name = "como", editable = "." }, - { name = "pandas-stubs", specifier = ">=2.3.2.250827" }, - { name = "pre-commit", specifier = ">=4.2.0" }, - { name = "pytest", specifier = ">=8.4.1" }, - { name = "pytest-asyncio", specifier = ">=1.1.0" }, - { name = "pytest-cov", specifier = ">=6.2.1" }, - { name = "ruff", specifier = ">=0.12.11" }, - { name = "scipy-stubs", specifier = ">=1.16.1.1" }, - { name = "types-aiofiles", specifier = ">=24.1.0.20250822" }, -] - [[package]] name = "contourpy" version = "1.3.3" @@ -603,55 +577,63 @@ wheels = [ [[package]] name = "coverage" -version = "7.10.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/14/70/025b179c993f019105b79575ac6edb5e084fb0f0e63f15cdebef4e454fb5/coverage-7.10.6.tar.gz", hash = "sha256:f644a3ae5933a552a29dbb9aa2f90c677a875f80ebea028e5a52a4f429044b90", size = 823736, upload-time = "2025-08-29T15:35:16.668Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d4/16/2bea27e212c4980753d6d563a0803c150edeaaddb0771a50d2afc410a261/coverage-7.10.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c706db3cabb7ceef779de68270150665e710b46d56372455cd741184f3868d8f", size = 217129, upload-time = "2025-08-29T15:33:13.575Z" }, - { url = "https://files.pythonhosted.org/packages/2a/51/e7159e068831ab37e31aac0969d47b8c5ee25b7d307b51e310ec34869315/coverage-7.10.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e0c38dc289e0508ef68ec95834cb5d2e96fdbe792eaccaa1bccac3966bbadcc", size = 217532, upload-time = "2025-08-29T15:33:14.872Z" }, - { url = "https://files.pythonhosted.org/packages/e7/c0/246ccbea53d6099325d25cd208df94ea435cd55f0db38099dd721efc7a1f/coverage-7.10.6-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:752a3005a1ded28f2f3a6e8787e24f28d6abe176ca64677bcd8d53d6fe2ec08a", size = 247931, upload-time = "2025-08-29T15:33:16.142Z" }, - { url = "https://files.pythonhosted.org/packages/7d/fb/7435ef8ab9b2594a6e3f58505cc30e98ae8b33265d844007737946c59389/coverage-7.10.6-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:689920ecfd60f992cafca4f5477d55720466ad2c7fa29bb56ac8d44a1ac2b47a", size = 249864, upload-time = "2025-08-29T15:33:17.434Z" }, - { url = "https://files.pythonhosted.org/packages/51/f8/d9d64e8da7bcddb094d511154824038833c81e3a039020a9d6539bf303e9/coverage-7.10.6-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ec98435796d2624d6905820a42f82149ee9fc4f2d45c2c5bc5a44481cc50db62", size = 251969, upload-time = "2025-08-29T15:33:18.822Z" }, - { url = "https://files.pythonhosted.org/packages/43/28/c43ba0ef19f446d6463c751315140d8f2a521e04c3e79e5c5fe211bfa430/coverage-7.10.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b37201ce4a458c7a758ecc4efa92fa8ed783c66e0fa3c42ae19fc454a0792153", size = 249659, upload-time = "2025-08-29T15:33:20.407Z" }, - { url = "https://files.pythonhosted.org/packages/79/3e/53635bd0b72beaacf265784508a0b386defc9ab7fad99ff95f79ce9db555/coverage-7.10.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:2904271c80898663c810a6b067920a61dd8d38341244a3605bd31ab55250dad5", size = 247714, upload-time = "2025-08-29T15:33:21.751Z" }, - { url = "https://files.pythonhosted.org/packages/4c/55/0964aa87126624e8c159e32b0bc4e84edef78c89a1a4b924d28dd8265625/coverage-7.10.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5aea98383463d6e1fa4e95416d8de66f2d0cb588774ee20ae1b28df826bcb619", size = 248351, upload-time = "2025-08-29T15:33:23.105Z" }, - { url = "https://files.pythonhosted.org/packages/eb/ab/6cfa9dc518c6c8e14a691c54e53a9433ba67336c760607e299bfcf520cb1/coverage-7.10.6-cp311-cp311-win32.whl", hash = "sha256:e3fb1fa01d3598002777dd259c0c2e6d9d5e10e7222976fc8e03992f972a2cba", size = 219562, upload-time = "2025-08-29T15:33:24.717Z" }, - { url = "https://files.pythonhosted.org/packages/5b/18/99b25346690cbc55922e7cfef06d755d4abee803ef335baff0014268eff4/coverage-7.10.6-cp311-cp311-win_amd64.whl", hash = "sha256:f35ed9d945bece26553d5b4c8630453169672bea0050a564456eb88bdffd927e", size = 220453, upload-time = "2025-08-29T15:33:26.482Z" }, - { url = "https://files.pythonhosted.org/packages/d8/ed/81d86648a07ccb124a5cf1f1a7788712b8d7216b593562683cd5c9b0d2c1/coverage-7.10.6-cp311-cp311-win_arm64.whl", hash = "sha256:99e1a305c7765631d74b98bf7dbf54eeea931f975e80f115437d23848ee8c27c", size = 219127, upload-time = "2025-08-29T15:33:27.777Z" }, - { url = "https://files.pythonhosted.org/packages/26/06/263f3305c97ad78aab066d116b52250dd316e74fcc20c197b61e07eb391a/coverage-7.10.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5b2dd6059938063a2c9fee1af729d4f2af28fd1a545e9b7652861f0d752ebcea", size = 217324, upload-time = "2025-08-29T15:33:29.06Z" }, - { url = "https://files.pythonhosted.org/packages/e9/60/1e1ded9a4fe80d843d7d53b3e395c1db3ff32d6c301e501f393b2e6c1c1f/coverage-7.10.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:388d80e56191bf846c485c14ae2bc8898aa3124d9d35903fef7d907780477634", size = 217560, upload-time = "2025-08-29T15:33:30.748Z" }, - { url = "https://files.pythonhosted.org/packages/b8/25/52136173c14e26dfed8b106ed725811bb53c30b896d04d28d74cb64318b3/coverage-7.10.6-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:90cb5b1a4670662719591aa92d0095bb41714970c0b065b02a2610172dbf0af6", size = 249053, upload-time = "2025-08-29T15:33:32.041Z" }, - { url = "https://files.pythonhosted.org/packages/cb/1d/ae25a7dc58fcce8b172d42ffe5313fc267afe61c97fa872b80ee72d9515a/coverage-7.10.6-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:961834e2f2b863a0e14260a9a273aff07ff7818ab6e66d2addf5628590c628f9", size = 251802, upload-time = "2025-08-29T15:33:33.625Z" }, - { url = "https://files.pythonhosted.org/packages/f5/7a/1f561d47743710fe996957ed7c124b421320f150f1d38523d8d9102d3e2a/coverage-7.10.6-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf9a19f5012dab774628491659646335b1928cfc931bf8d97b0d5918dd58033c", size = 252935, upload-time = "2025-08-29T15:33:34.909Z" }, - { url = "https://files.pythonhosted.org/packages/6c/ad/8b97cd5d28aecdfde792dcbf646bac141167a5cacae2cd775998b45fabb5/coverage-7.10.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:99c4283e2a0e147b9c9cc6bc9c96124de9419d6044837e9799763a0e29a7321a", size = 250855, upload-time = "2025-08-29T15:33:36.922Z" }, - { url = "https://files.pythonhosted.org/packages/33/6a/95c32b558d9a61858ff9d79580d3877df3eb5bc9eed0941b1f187c89e143/coverage-7.10.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:282b1b20f45df57cc508c1e033403f02283adfb67d4c9c35a90281d81e5c52c5", size = 248974, upload-time = "2025-08-29T15:33:38.175Z" }, - { url = "https://files.pythonhosted.org/packages/0d/9c/8ce95dee640a38e760d5b747c10913e7a06554704d60b41e73fdea6a1ffd/coverage-7.10.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8cdbe264f11afd69841bd8c0d83ca10b5b32853263ee62e6ac6a0ab63895f972", size = 250409, upload-time = "2025-08-29T15:33:39.447Z" }, - { url = "https://files.pythonhosted.org/packages/04/12/7a55b0bdde78a98e2eb2356771fd2dcddb96579e8342bb52aa5bc52e96f0/coverage-7.10.6-cp312-cp312-win32.whl", hash = "sha256:a517feaf3a0a3eca1ee985d8373135cfdedfbba3882a5eab4362bda7c7cf518d", size = 219724, upload-time = "2025-08-29T15:33:41.172Z" }, - { url = "https://files.pythonhosted.org/packages/36/4a/32b185b8b8e327802c9efce3d3108d2fe2d9d31f153a0f7ecfd59c773705/coverage-7.10.6-cp312-cp312-win_amd64.whl", hash = "sha256:856986eadf41f52b214176d894a7de05331117f6035a28ac0016c0f63d887629", size = 220536, upload-time = "2025-08-29T15:33:42.524Z" }, - { url = "https://files.pythonhosted.org/packages/08/3a/d5d8dc703e4998038c3099eaf77adddb00536a3cec08c8dcd556a36a3eb4/coverage-7.10.6-cp312-cp312-win_arm64.whl", hash = "sha256:acf36b8268785aad739443fa2780c16260ee3fa09d12b3a70f772ef100939d80", size = 219171, upload-time = "2025-08-29T15:33:43.974Z" }, - { url = "https://files.pythonhosted.org/packages/bd/e7/917e5953ea29a28c1057729c1d5af9084ab6d9c66217523fd0e10f14d8f6/coverage-7.10.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ffea0575345e9ee0144dfe5701aa17f3ba546f8c3bb48db62ae101afb740e7d6", size = 217351, upload-time = "2025-08-29T15:33:45.438Z" }, - { url = "https://files.pythonhosted.org/packages/eb/86/2e161b93a4f11d0ea93f9bebb6a53f113d5d6e416d7561ca41bb0a29996b/coverage-7.10.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:95d91d7317cde40a1c249d6b7382750b7e6d86fad9d8eaf4fa3f8f44cf171e80", size = 217600, upload-time = "2025-08-29T15:33:47.269Z" }, - { url = "https://files.pythonhosted.org/packages/0e/66/d03348fdd8df262b3a7fb4ee5727e6e4936e39e2f3a842e803196946f200/coverage-7.10.6-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3e23dd5408fe71a356b41baa82892772a4cefcf758f2ca3383d2aa39e1b7a003", size = 248600, upload-time = "2025-08-29T15:33:48.953Z" }, - { url = "https://files.pythonhosted.org/packages/73/dd/508420fb47d09d904d962f123221bc249f64b5e56aa93d5f5f7603be475f/coverage-7.10.6-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0f3f56e4cb573755e96a16501a98bf211f100463d70275759e73f3cbc00d4f27", size = 251206, upload-time = "2025-08-29T15:33:50.697Z" }, - { url = "https://files.pythonhosted.org/packages/e9/1f/9020135734184f439da85c70ea78194c2730e56c2d18aee6e8ff1719d50d/coverage-7.10.6-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:db4a1d897bbbe7339946ffa2fe60c10cc81c43fab8b062d3fcb84188688174a4", size = 252478, upload-time = "2025-08-29T15:33:52.303Z" }, - { url = "https://files.pythonhosted.org/packages/a4/a4/3d228f3942bb5a2051fde28c136eea23a761177dc4ff4ef54533164ce255/coverage-7.10.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d8fd7879082953c156d5b13c74aa6cca37f6a6f4747b39538504c3f9c63d043d", size = 250637, upload-time = "2025-08-29T15:33:53.67Z" }, - { url = "https://files.pythonhosted.org/packages/36/e3/293dce8cdb9a83de971637afc59b7190faad60603b40e32635cbd15fbf61/coverage-7.10.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:28395ca3f71cd103b8c116333fa9db867f3a3e1ad6a084aa3725ae002b6583bc", size = 248529, upload-time = "2025-08-29T15:33:55.022Z" }, - { url = "https://files.pythonhosted.org/packages/90/26/64eecfa214e80dd1d101e420cab2901827de0e49631d666543d0e53cf597/coverage-7.10.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:61c950fc33d29c91b9e18540e1aed7d9f6787cc870a3e4032493bbbe641d12fc", size = 250143, upload-time = "2025-08-29T15:33:56.386Z" }, - { url = "https://files.pythonhosted.org/packages/3e/70/bd80588338f65ea5b0d97e424b820fb4068b9cfb9597fbd91963086e004b/coverage-7.10.6-cp313-cp313-win32.whl", hash = "sha256:160c00a5e6b6bdf4e5984b0ef21fc860bc94416c41b7df4d63f536d17c38902e", size = 219770, upload-time = "2025-08-29T15:33:58.063Z" }, - { url = "https://files.pythonhosted.org/packages/a7/14/0b831122305abcc1060c008f6c97bbdc0a913ab47d65070a01dc50293c2b/coverage-7.10.6-cp313-cp313-win_amd64.whl", hash = "sha256:628055297f3e2aa181464c3808402887643405573eb3d9de060d81531fa79d32", size = 220566, upload-time = "2025-08-29T15:33:59.766Z" }, - { url = "https://files.pythonhosted.org/packages/83/c6/81a83778c1f83f1a4a168ed6673eeedc205afb562d8500175292ca64b94e/coverage-7.10.6-cp313-cp313-win_arm64.whl", hash = "sha256:df4ec1f8540b0bcbe26ca7dd0f541847cc8a108b35596f9f91f59f0c060bfdd2", size = 219195, upload-time = "2025-08-29T15:34:01.191Z" }, - { url = "https://files.pythonhosted.org/packages/d7/1c/ccccf4bf116f9517275fa85047495515add43e41dfe8e0bef6e333c6b344/coverage-7.10.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:c9a8b7a34a4de3ed987f636f71881cd3b8339f61118b1aa311fbda12741bff0b", size = 218059, upload-time = "2025-08-29T15:34:02.91Z" }, - { url = "https://files.pythonhosted.org/packages/92/97/8a3ceff833d27c7492af4f39d5da6761e9ff624831db9e9f25b3886ddbca/coverage-7.10.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8dd5af36092430c2b075cee966719898f2ae87b636cefb85a653f1d0ba5d5393", size = 218287, upload-time = "2025-08-29T15:34:05.106Z" }, - { url = "https://files.pythonhosted.org/packages/92/d8/50b4a32580cf41ff0423777a2791aaf3269ab60c840b62009aec12d3970d/coverage-7.10.6-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b0353b0f0850d49ada66fdd7d0c7cdb0f86b900bb9e367024fd14a60cecc1e27", size = 259625, upload-time = "2025-08-29T15:34:06.575Z" }, - { url = "https://files.pythonhosted.org/packages/7e/7e/6a7df5a6fb440a0179d94a348eb6616ed4745e7df26bf2a02bc4db72c421/coverage-7.10.6-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d6b9ae13d5d3e8aeca9ca94198aa7b3ebbc5acfada557d724f2a1f03d2c0b0df", size = 261801, upload-time = "2025-08-29T15:34:08.006Z" }, - { url = "https://files.pythonhosted.org/packages/3a/4c/a270a414f4ed5d196b9d3d67922968e768cd971d1b251e1b4f75e9362f75/coverage-7.10.6-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:675824a363cc05781b1527b39dc2587b8984965834a748177ee3c37b64ffeafb", size = 264027, upload-time = "2025-08-29T15:34:09.806Z" }, - { url = "https://files.pythonhosted.org/packages/9c/8b/3210d663d594926c12f373c5370bf1e7c5c3a427519a8afa65b561b9a55c/coverage-7.10.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:692d70ea725f471a547c305f0d0fc6a73480c62fb0da726370c088ab21aed282", size = 261576, upload-time = "2025-08-29T15:34:11.585Z" }, - { url = "https://files.pythonhosted.org/packages/72/d0/e1961eff67e9e1dba3fc5eb7a4caf726b35a5b03776892da8d79ec895775/coverage-7.10.6-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:851430a9a361c7a8484a36126d1d0ff8d529d97385eacc8dfdc9bfc8c2d2cbe4", size = 259341, upload-time = "2025-08-29T15:34:13.159Z" }, - { url = "https://files.pythonhosted.org/packages/3a/06/d6478d152cd189b33eac691cba27a40704990ba95de49771285f34a5861e/coverage-7.10.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d9369a23186d189b2fc95cc08b8160ba242057e887d766864f7adf3c46b2df21", size = 260468, upload-time = "2025-08-29T15:34:14.571Z" }, - { url = "https://files.pythonhosted.org/packages/ed/73/737440247c914a332f0b47f7598535b29965bf305e19bbc22d4c39615d2b/coverage-7.10.6-cp313-cp313t-win32.whl", hash = "sha256:92be86fcb125e9bda0da7806afd29a3fd33fdf58fba5d60318399adf40bf37d0", size = 220429, upload-time = "2025-08-29T15:34:16.394Z" }, - { url = "https://files.pythonhosted.org/packages/bd/76/b92d3214740f2357ef4a27c75a526eb6c28f79c402e9f20a922c295c05e2/coverage-7.10.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6b3039e2ca459a70c79523d39347d83b73f2f06af5624905eba7ec34d64d80b5", size = 221493, upload-time = "2025-08-29T15:34:17.835Z" }, - { url = "https://files.pythonhosted.org/packages/fc/8e/6dcb29c599c8a1f654ec6cb68d76644fe635513af16e932d2d4ad1e5ac6e/coverage-7.10.6-cp313-cp313t-win_arm64.whl", hash = "sha256:3fb99d0786fe17b228eab663d16bee2288e8724d26a199c29325aac4b0319b9b", size = 219757, upload-time = "2025-08-29T15:34:19.248Z" }, - { url = "https://files.pythonhosted.org/packages/44/0c/50db5379b615854b5cf89146f8f5bd1d5a9693d7f3a987e269693521c404/coverage-7.10.6-py3-none-any.whl", hash = "sha256:92c4ecf6bf11b2e85fd4d8204814dc26e6a19f0c9d938c207c5cb0eadfcabbe3", size = 208986, upload-time = "2025-08-29T15:35:14.506Z" }, +version = "7.10.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/51/26/d22c300112504f5f9a9fd2297ce33c35f3d353e4aeb987c8419453b2a7c2/coverage-7.10.7.tar.gz", hash = "sha256:f4ab143ab113be368a3e9b795f9cd7906c5ef407d6173fe9675a902e1fffc239", size = 827704, upload-time = "2025-09-21T20:03:56.815Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/5d/c1a17867b0456f2e9ce2d8d4708a4c3a089947d0bec9c66cdf60c9e7739f/coverage-7.10.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a609f9c93113be646f44c2a0256d6ea375ad047005d7f57a5c15f614dc1b2f59", size = 218102, upload-time = "2025-09-21T20:01:16.089Z" }, + { url = "https://files.pythonhosted.org/packages/54/f0/514dcf4b4e3698b9a9077f084429681bf3aad2b4a72578f89d7f643eb506/coverage-7.10.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:65646bb0359386e07639c367a22cf9b5bf6304e8630b565d0626e2bdf329227a", size = 218505, upload-time = "2025-09-21T20:01:17.788Z" }, + { url = "https://files.pythonhosted.org/packages/20/f6/9626b81d17e2a4b25c63ac1b425ff307ecdeef03d67c9a147673ae40dc36/coverage-7.10.7-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5f33166f0dfcce728191f520bd2692914ec70fac2713f6bf3ce59c3deacb4699", size = 248898, upload-time = "2025-09-21T20:01:19.488Z" }, + { url = "https://files.pythonhosted.org/packages/b0/ef/bd8e719c2f7417ba03239052e099b76ea1130ac0cbb183ee1fcaa58aaff3/coverage-7.10.7-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:35f5e3f9e455bb17831876048355dca0f758b6df22f49258cb5a91da23ef437d", size = 250831, upload-time = "2025-09-21T20:01:20.817Z" }, + { url = "https://files.pythonhosted.org/packages/a5/b6/bf054de41ec948b151ae2b79a55c107f5760979538f5fb80c195f2517718/coverage-7.10.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4da86b6d62a496e908ac2898243920c7992499c1712ff7c2b6d837cc69d9467e", size = 252937, upload-time = "2025-09-21T20:01:22.171Z" }, + { url = "https://files.pythonhosted.org/packages/0f/e5/3860756aa6f9318227443c6ce4ed7bf9e70bb7f1447a0353f45ac5c7974b/coverage-7.10.7-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6b8b09c1fad947c84bbbc95eca841350fad9cbfa5a2d7ca88ac9f8d836c92e23", size = 249021, upload-time = "2025-09-21T20:01:23.907Z" }, + { url = "https://files.pythonhosted.org/packages/26/0f/bd08bd042854f7fd07b45808927ebcce99a7ed0f2f412d11629883517ac2/coverage-7.10.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4376538f36b533b46f8971d3a3e63464f2c7905c9800db97361c43a2b14792ab", size = 250626, upload-time = "2025-09-21T20:01:25.721Z" }, + { url = "https://files.pythonhosted.org/packages/8e/a7/4777b14de4abcc2e80c6b1d430f5d51eb18ed1d75fca56cbce5f2db9b36e/coverage-7.10.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:121da30abb574f6ce6ae09840dae322bef734480ceafe410117627aa54f76d82", size = 248682, upload-time = "2025-09-21T20:01:27.105Z" }, + { url = "https://files.pythonhosted.org/packages/34/72/17d082b00b53cd45679bad682fac058b87f011fd8b9fe31d77f5f8d3a4e4/coverage-7.10.7-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:88127d40df529336a9836870436fc2751c339fbaed3a836d42c93f3e4bd1d0a2", size = 248402, upload-time = "2025-09-21T20:01:28.629Z" }, + { url = "https://files.pythonhosted.org/packages/81/7a/92367572eb5bdd6a84bfa278cc7e97db192f9f45b28c94a9ca1a921c3577/coverage-7.10.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ba58bbcd1b72f136080c0bccc2400d66cc6115f3f906c499013d065ac33a4b61", size = 249320, upload-time = "2025-09-21T20:01:30.004Z" }, + { url = "https://files.pythonhosted.org/packages/2f/88/a23cc185f6a805dfc4fdf14a94016835eeb85e22ac3a0e66d5e89acd6462/coverage-7.10.7-cp311-cp311-win32.whl", hash = "sha256:972b9e3a4094b053a4e46832b4bc829fc8a8d347160eb39d03f1690316a99c14", size = 220536, upload-time = "2025-09-21T20:01:32.184Z" }, + { url = "https://files.pythonhosted.org/packages/fe/ef/0b510a399dfca17cec7bc2f05ad8bd78cf55f15c8bc9a73ab20c5c913c2e/coverage-7.10.7-cp311-cp311-win_amd64.whl", hash = "sha256:a7b55a944a7f43892e28ad4bc0561dfd5f0d73e605d1aa5c3c976b52aea121d2", size = 221425, upload-time = "2025-09-21T20:01:33.557Z" }, + { url = "https://files.pythonhosted.org/packages/51/7f/023657f301a276e4ba1850f82749bc136f5a7e8768060c2e5d9744a22951/coverage-7.10.7-cp311-cp311-win_arm64.whl", hash = "sha256:736f227fb490f03c6488f9b6d45855f8e0fd749c007f9303ad30efab0e73c05a", size = 220103, upload-time = "2025-09-21T20:01:34.929Z" }, + { url = "https://files.pythonhosted.org/packages/13/e4/eb12450f71b542a53972d19117ea5a5cea1cab3ac9e31b0b5d498df1bd5a/coverage-7.10.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7bb3b9ddb87ef7725056572368040c32775036472d5a033679d1fa6c8dc08417", size = 218290, upload-time = "2025-09-21T20:01:36.455Z" }, + { url = "https://files.pythonhosted.org/packages/37/66/593f9be12fc19fb36711f19a5371af79a718537204d16ea1d36f16bd78d2/coverage-7.10.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:18afb24843cbc175687225cab1138c95d262337f5473512010e46831aa0c2973", size = 218515, upload-time = "2025-09-21T20:01:37.982Z" }, + { url = "https://files.pythonhosted.org/packages/66/80/4c49f7ae09cafdacc73fbc30949ffe77359635c168f4e9ff33c9ebb07838/coverage-7.10.7-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:399a0b6347bcd3822be369392932884b8216d0944049ae22925631a9b3d4ba4c", size = 250020, upload-time = "2025-09-21T20:01:39.617Z" }, + { url = "https://files.pythonhosted.org/packages/a6/90/a64aaacab3b37a17aaedd83e8000142561a29eb262cede42d94a67f7556b/coverage-7.10.7-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:314f2c326ded3f4b09be11bc282eb2fc861184bc95748ae67b360ac962770be7", size = 252769, upload-time = "2025-09-21T20:01:41.341Z" }, + { url = "https://files.pythonhosted.org/packages/98/2e/2dda59afd6103b342e096f246ebc5f87a3363b5412609946c120f4e7750d/coverage-7.10.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c41e71c9cfb854789dee6fc51e46743a6d138b1803fab6cb860af43265b42ea6", size = 253901, upload-time = "2025-09-21T20:01:43.042Z" }, + { url = "https://files.pythonhosted.org/packages/53/dc/8d8119c9051d50f3119bb4a75f29f1e4a6ab9415cd1fa8bf22fcc3fb3b5f/coverage-7.10.7-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc01f57ca26269c2c706e838f6422e2a8788e41b3e3c65e2f41148212e57cd59", size = 250413, upload-time = "2025-09-21T20:01:44.469Z" }, + { url = "https://files.pythonhosted.org/packages/98/b3/edaff9c5d79ee4d4b6d3fe046f2b1d799850425695b789d491a64225d493/coverage-7.10.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a6442c59a8ac8b85812ce33bc4d05bde3fb22321fa8294e2a5b487c3505f611b", size = 251820, upload-time = "2025-09-21T20:01:45.915Z" }, + { url = "https://files.pythonhosted.org/packages/11/25/9a0728564bb05863f7e513e5a594fe5ffef091b325437f5430e8cfb0d530/coverage-7.10.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:78a384e49f46b80fb4c901d52d92abe098e78768ed829c673fbb53c498bef73a", size = 249941, upload-time = "2025-09-21T20:01:47.296Z" }, + { url = "https://files.pythonhosted.org/packages/e0/fd/ca2650443bfbef5b0e74373aac4df67b08180d2f184b482c41499668e258/coverage-7.10.7-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:5e1e9802121405ede4b0133aa4340ad8186a1d2526de5b7c3eca519db7bb89fb", size = 249519, upload-time = "2025-09-21T20:01:48.73Z" }, + { url = "https://files.pythonhosted.org/packages/24/79/f692f125fb4299b6f963b0745124998ebb8e73ecdfce4ceceb06a8c6bec5/coverage-7.10.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d41213ea25a86f69efd1575073d34ea11aabe075604ddf3d148ecfec9e1e96a1", size = 251375, upload-time = "2025-09-21T20:01:50.529Z" }, + { url = "https://files.pythonhosted.org/packages/5e/75/61b9bbd6c7d24d896bfeec57acba78e0f8deac68e6baf2d4804f7aae1f88/coverage-7.10.7-cp312-cp312-win32.whl", hash = "sha256:77eb4c747061a6af8d0f7bdb31f1e108d172762ef579166ec84542f711d90256", size = 220699, upload-time = "2025-09-21T20:01:51.941Z" }, + { url = "https://files.pythonhosted.org/packages/ca/f3/3bf7905288b45b075918d372498f1cf845b5b579b723c8fd17168018d5f5/coverage-7.10.7-cp312-cp312-win_amd64.whl", hash = "sha256:f51328ffe987aecf6d09f3cd9d979face89a617eacdaea43e7b3080777f647ba", size = 221512, upload-time = "2025-09-21T20:01:53.481Z" }, + { url = "https://files.pythonhosted.org/packages/5c/44/3e32dbe933979d05cf2dac5e697c8599cfe038aaf51223ab901e208d5a62/coverage-7.10.7-cp312-cp312-win_arm64.whl", hash = "sha256:bda5e34f8a75721c96085903c6f2197dc398c20ffd98df33f866a9c8fd95f4bf", size = 220147, upload-time = "2025-09-21T20:01:55.2Z" }, + { url = "https://files.pythonhosted.org/packages/9a/94/b765c1abcb613d103b64fcf10395f54d69b0ef8be6a0dd9c524384892cc7/coverage-7.10.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:981a651f543f2854abd3b5fcb3263aac581b18209be49863ba575de6edf4c14d", size = 218320, upload-time = "2025-09-21T20:01:56.629Z" }, + { url = "https://files.pythonhosted.org/packages/72/4f/732fff31c119bb73b35236dd333030f32c4bfe909f445b423e6c7594f9a2/coverage-7.10.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:73ab1601f84dc804f7812dc297e93cd99381162da39c47040a827d4e8dafe63b", size = 218575, upload-time = "2025-09-21T20:01:58.203Z" }, + { url = "https://files.pythonhosted.org/packages/87/02/ae7e0af4b674be47566707777db1aa375474f02a1d64b9323e5813a6cdd5/coverage-7.10.7-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a8b6f03672aa6734e700bbcd65ff050fd19cddfec4b031cc8cf1c6967de5a68e", size = 249568, upload-time = "2025-09-21T20:01:59.748Z" }, + { url = "https://files.pythonhosted.org/packages/a2/77/8c6d22bf61921a59bce5471c2f1f7ac30cd4ac50aadde72b8c48d5727902/coverage-7.10.7-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:10b6ba00ab1132a0ce4428ff68cf50a25efd6840a42cdf4239c9b99aad83be8b", size = 252174, upload-time = "2025-09-21T20:02:01.192Z" }, + { url = "https://files.pythonhosted.org/packages/b1/20/b6ea4f69bbb52dac0aebd62157ba6a9dddbfe664f5af8122dac296c3ee15/coverage-7.10.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c79124f70465a150e89340de5963f936ee97097d2ef76c869708c4248c63ca49", size = 253447, upload-time = "2025-09-21T20:02:02.701Z" }, + { url = "https://files.pythonhosted.org/packages/f9/28/4831523ba483a7f90f7b259d2018fef02cb4d5b90bc7c1505d6e5a84883c/coverage-7.10.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:69212fbccdbd5b0e39eac4067e20a4a5256609e209547d86f740d68ad4f04911", size = 249779, upload-time = "2025-09-21T20:02:04.185Z" }, + { url = "https://files.pythonhosted.org/packages/a7/9f/4331142bc98c10ca6436d2d620c3e165f31e6c58d43479985afce6f3191c/coverage-7.10.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7ea7c6c9d0d286d04ed3541747e6597cbe4971f22648b68248f7ddcd329207f0", size = 251604, upload-time = "2025-09-21T20:02:06.034Z" }, + { url = "https://files.pythonhosted.org/packages/ce/60/bda83b96602036b77ecf34e6393a3836365481b69f7ed7079ab85048202b/coverage-7.10.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b9be91986841a75042b3e3243d0b3cb0b2434252b977baaf0cd56e960fe1e46f", size = 249497, upload-time = "2025-09-21T20:02:07.619Z" }, + { url = "https://files.pythonhosted.org/packages/5f/af/152633ff35b2af63977edd835d8e6430f0caef27d171edf2fc76c270ef31/coverage-7.10.7-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:b281d5eca50189325cfe1f365fafade89b14b4a78d9b40b05ddd1fc7d2a10a9c", size = 249350, upload-time = "2025-09-21T20:02:10.34Z" }, + { url = "https://files.pythonhosted.org/packages/9d/71/d92105d122bd21cebba877228990e1646d862e34a98bb3374d3fece5a794/coverage-7.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:99e4aa63097ab1118e75a848a28e40d68b08a5e19ce587891ab7fd04475e780f", size = 251111, upload-time = "2025-09-21T20:02:12.122Z" }, + { url = "https://files.pythonhosted.org/packages/a2/9e/9fdb08f4bf476c912f0c3ca292e019aab6712c93c9344a1653986c3fd305/coverage-7.10.7-cp313-cp313-win32.whl", hash = "sha256:dc7c389dce432500273eaf48f410b37886be9208b2dd5710aaf7c57fd442c698", size = 220746, upload-time = "2025-09-21T20:02:13.919Z" }, + { url = "https://files.pythonhosted.org/packages/b1/b1/a75fd25df44eab52d1931e89980d1ada46824c7a3210be0d3c88a44aaa99/coverage-7.10.7-cp313-cp313-win_amd64.whl", hash = "sha256:cac0fdca17b036af3881a9d2729a850b76553f3f716ccb0360ad4dbc06b3b843", size = 221541, upload-time = "2025-09-21T20:02:15.57Z" }, + { url = "https://files.pythonhosted.org/packages/14/3a/d720d7c989562a6e9a14b2c9f5f2876bdb38e9367126d118495b89c99c37/coverage-7.10.7-cp313-cp313-win_arm64.whl", hash = "sha256:4b6f236edf6e2f9ae8fcd1332da4e791c1b6ba0dc16a2dc94590ceccb482e546", size = 220170, upload-time = "2025-09-21T20:02:17.395Z" }, + { url = "https://files.pythonhosted.org/packages/bb/22/e04514bf2a735d8b0add31d2b4ab636fc02370730787c576bb995390d2d5/coverage-7.10.7-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a0ec07fd264d0745ee396b666d47cef20875f4ff2375d7c4f58235886cc1ef0c", size = 219029, upload-time = "2025-09-21T20:02:18.936Z" }, + { url = "https://files.pythonhosted.org/packages/11/0b/91128e099035ece15da3445d9015e4b4153a6059403452d324cbb0a575fa/coverage-7.10.7-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:dd5e856ebb7bfb7672b0086846db5afb4567a7b9714b8a0ebafd211ec7ce6a15", size = 219259, upload-time = "2025-09-21T20:02:20.44Z" }, + { url = "https://files.pythonhosted.org/packages/8b/51/66420081e72801536a091a0c8f8c1f88a5c4bf7b9b1bdc6222c7afe6dc9b/coverage-7.10.7-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f57b2a3c8353d3e04acf75b3fed57ba41f5c0646bbf1d10c7c282291c97936b4", size = 260592, upload-time = "2025-09-21T20:02:22.313Z" }, + { url = "https://files.pythonhosted.org/packages/5d/22/9b8d458c2881b22df3db5bb3e7369e63d527d986decb6c11a591ba2364f7/coverage-7.10.7-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1ef2319dd15a0b009667301a3f84452a4dc6fddfd06b0c5c53ea472d3989fbf0", size = 262768, upload-time = "2025-09-21T20:02:24.287Z" }, + { url = "https://files.pythonhosted.org/packages/f7/08/16bee2c433e60913c610ea200b276e8eeef084b0d200bdcff69920bd5828/coverage-7.10.7-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:83082a57783239717ceb0ad584de3c69cf581b2a95ed6bf81ea66034f00401c0", size = 264995, upload-time = "2025-09-21T20:02:26.133Z" }, + { url = "https://files.pythonhosted.org/packages/20/9d/e53eb9771d154859b084b90201e5221bca7674ba449a17c101a5031d4054/coverage-7.10.7-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:50aa94fb1fb9a397eaa19c0d5ec15a5edd03a47bf1a3a6111a16b36e190cff65", size = 259546, upload-time = "2025-09-21T20:02:27.716Z" }, + { url = "https://files.pythonhosted.org/packages/ad/b0/69bc7050f8d4e56a89fb550a1577d5d0d1db2278106f6f626464067b3817/coverage-7.10.7-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2120043f147bebb41c85b97ac45dd173595ff14f2a584f2963891cbcc3091541", size = 262544, upload-time = "2025-09-21T20:02:29.216Z" }, + { url = "https://files.pythonhosted.org/packages/ef/4b/2514b060dbd1bc0aaf23b852c14bb5818f244c664cb16517feff6bb3a5ab/coverage-7.10.7-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:2fafd773231dd0378fdba66d339f84904a8e57a262f583530f4f156ab83863e6", size = 260308, upload-time = "2025-09-21T20:02:31.226Z" }, + { url = "https://files.pythonhosted.org/packages/54/78/7ba2175007c246d75e496f64c06e94122bdb914790a1285d627a918bd271/coverage-7.10.7-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:0b944ee8459f515f28b851728ad224fa2d068f1513ef6b7ff1efafeb2185f999", size = 258920, upload-time = "2025-09-21T20:02:32.823Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b3/fac9f7abbc841409b9a410309d73bfa6cfb2e51c3fada738cb607ce174f8/coverage-7.10.7-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4b583b97ab2e3efe1b3e75248a9b333bd3f8b0b1b8e5b45578e05e5850dfb2c2", size = 261434, upload-time = "2025-09-21T20:02:34.86Z" }, + { url = "https://files.pythonhosted.org/packages/ee/51/a03bec00d37faaa891b3ff7387192cef20f01604e5283a5fabc95346befa/coverage-7.10.7-cp313-cp313t-win32.whl", hash = "sha256:2a78cd46550081a7909b3329e2266204d584866e8d97b898cd7fb5ac8d888b1a", size = 221403, upload-time = "2025-09-21T20:02:37.034Z" }, + { url = "https://files.pythonhosted.org/packages/53/22/3cf25d614e64bf6d8e59c7c669b20d6d940bb337bdee5900b9ca41c820bb/coverage-7.10.7-cp313-cp313t-win_amd64.whl", hash = "sha256:33a5e6396ab684cb43dc7befa386258acb2d7fae7f67330ebb85ba4ea27938eb", size = 222469, upload-time = "2025-09-21T20:02:39.011Z" }, + { url = "https://files.pythonhosted.org/packages/49/a1/00164f6d30d8a01c3c9c48418a7a5be394de5349b421b9ee019f380df2a0/coverage-7.10.7-cp313-cp313t-win_arm64.whl", hash = "sha256:86b0e7308289ddde73d863b7683f596d8d21c7d8664ce1dee061d0bcf3fbb4bb", size = 220731, upload-time = "2025-09-21T20:02:40.939Z" }, + { url = "https://files.pythonhosted.org/packages/ec/16/114df1c291c22cac3b0c127a73e0af5c12ed7bbb6558d310429a0ae24023/coverage-7.10.7-py3-none-any.whl", hash = "sha256:f7941f6f2fe6dd6807a1208737b8a0cbcf1cc6d7b07d24998ad2d63590868260", size = 209952, upload-time = "2025-09-21T20:03:53.918Z" }, ] [package.optional-dependencies] @@ -722,23 +704,23 @@ wheels = [ [[package]] name = "debugpy" -version = "1.8.16" +version = "1.8.17" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ca/d4/722d0bcc7986172ac2ef3c979ad56a1030e3afd44ced136d45f8142b1f4a/debugpy-1.8.16.tar.gz", hash = "sha256:31e69a1feb1cf6b51efbed3f6c9b0ef03bc46ff050679c4be7ea6d2e23540870", size = 1643809, upload-time = "2025-08-06T18:00:02.647Z" } +sdist = { url = "https://files.pythonhosted.org/packages/15/ad/71e708ff4ca377c4230530d6a7aa7992592648c122a2cd2b321cf8b35a76/debugpy-1.8.17.tar.gz", hash = "sha256:fd723b47a8c08892b1a16b2c6239a8b96637c62a59b94bb5dab4bac592a58a8e", size = 1644129, upload-time = "2025-09-17T16:33:20.633Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/63/d6/ad70ba8b49b23fa286fb21081cf732232cc19374af362051da9c7537ae52/debugpy-1.8.16-cp311-cp311-macosx_14_0_universal2.whl", hash = "sha256:67371b28b79a6a12bcc027d94a06158f2fde223e35b5c4e0783b6f9d3b39274a", size = 2184063, upload-time = "2025-08-06T18:00:11.885Z" }, - { url = "https://files.pythonhosted.org/packages/aa/49/7b03e88dea9759a4c7910143f87f92beb494daaae25560184ff4ae883f9e/debugpy-1.8.16-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2abae6dd02523bec2dee16bd6b0781cccb53fd4995e5c71cc659b5f45581898", size = 3134837, upload-time = "2025-08-06T18:00:13.782Z" }, - { url = "https://files.pythonhosted.org/packages/5d/52/b348930316921de7565fbe37a487d15409041713004f3d74d03eb077dbd4/debugpy-1.8.16-cp311-cp311-win32.whl", hash = "sha256:f8340a3ac2ed4f5da59e064aa92e39edd52729a88fbde7bbaa54e08249a04493", size = 5159142, upload-time = "2025-08-06T18:00:15.391Z" }, - { url = "https://files.pythonhosted.org/packages/d8/ef/9aa9549ce1e10cea696d980292e71672a91ee4a6a691ce5f8629e8f48c49/debugpy-1.8.16-cp311-cp311-win_amd64.whl", hash = "sha256:70f5fcd6d4d0c150a878d2aa37391c52de788c3dc680b97bdb5e529cb80df87a", size = 5183117, upload-time = "2025-08-06T18:00:17.251Z" }, - { url = "https://files.pythonhosted.org/packages/61/fb/0387c0e108d842c902801bc65ccc53e5b91d8c169702a9bbf4f7efcedf0c/debugpy-1.8.16-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:b202e2843e32e80b3b584bcebfe0e65e0392920dc70df11b2bfe1afcb7a085e4", size = 2511822, upload-time = "2025-08-06T18:00:18.526Z" }, - { url = "https://files.pythonhosted.org/packages/37/44/19e02745cae22bf96440141f94e15a69a1afaa3a64ddfc38004668fcdebf/debugpy-1.8.16-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64473c4a306ba11a99fe0bb14622ba4fbd943eb004847d9b69b107bde45aa9ea", size = 4230135, upload-time = "2025-08-06T18:00:19.997Z" }, - { url = "https://files.pythonhosted.org/packages/f3/0b/19b1ba5ee4412f303475a2c7ad5858efb99c90eae5ec627aa6275c439957/debugpy-1.8.16-cp312-cp312-win32.whl", hash = "sha256:833a61ed446426e38b0dd8be3e9d45ae285d424f5bf6cd5b2b559c8f12305508", size = 5281271, upload-time = "2025-08-06T18:00:21.281Z" }, - { url = "https://files.pythonhosted.org/packages/b1/e0/bc62e2dc141de53bd03e2c7cb9d7011de2e65e8bdcdaa26703e4d28656ba/debugpy-1.8.16-cp312-cp312-win_amd64.whl", hash = "sha256:75f204684581e9ef3dc2f67687c3c8c183fde2d6675ab131d94084baf8084121", size = 5323149, upload-time = "2025-08-06T18:00:23.033Z" }, - { url = "https://files.pythonhosted.org/packages/62/66/607ab45cc79e60624df386e233ab64a6d8d39ea02e7f80e19c1d451345bb/debugpy-1.8.16-cp313-cp313-macosx_14_0_universal2.whl", hash = "sha256:85df3adb1de5258dca910ae0bb185e48c98801ec15018a263a92bb06be1c8787", size = 2496157, upload-time = "2025-08-06T18:00:24.361Z" }, - { url = "https://files.pythonhosted.org/packages/4d/a0/c95baae08a75bceabb79868d663a0736655e427ab9c81fb848da29edaeac/debugpy-1.8.16-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bee89e948bc236a5c43c4214ac62d28b29388453f5fd328d739035e205365f0b", size = 4222491, upload-time = "2025-08-06T18:00:25.806Z" }, - { url = "https://files.pythonhosted.org/packages/5b/2f/1c8db6ddd8a257c3cd2c46413b267f1d5fa3df910401c899513ce30392d6/debugpy-1.8.16-cp313-cp313-win32.whl", hash = "sha256:cf358066650439847ec5ff3dae1da98b5461ea5da0173d93d5e10f477c94609a", size = 5281126, upload-time = "2025-08-06T18:00:27.207Z" }, - { url = "https://files.pythonhosted.org/packages/d3/ba/c3e154ab307366d6c5a9c1b68de04914e2ce7fa2f50d578311d8cc5074b2/debugpy-1.8.16-cp313-cp313-win_amd64.whl", hash = "sha256:b5aea1083f6f50023e8509399d7dc6535a351cc9f2e8827d1e093175e4d9fa4c", size = 5323094, upload-time = "2025-08-06T18:00:29.03Z" }, - { url = "https://files.pythonhosted.org/packages/52/57/ecc9ae29fa5b2d90107cd1d9bf8ed19aacb74b2264d986ae9d44fe9bdf87/debugpy-1.8.16-py2.py3-none-any.whl", hash = "sha256:19c9521962475b87da6f673514f7fd610328757ec993bf7ec0d8c96f9a325f9e", size = 5287700, upload-time = "2025-08-06T18:00:42.333Z" }, + { url = "https://files.pythonhosted.org/packages/d8/53/3af72b5c159278c4a0cf4cffa518675a0e73bdb7d1cac0239b815502d2ce/debugpy-1.8.17-cp311-cp311-macosx_15_0_universal2.whl", hash = "sha256:d3fce3f0e3de262a3b67e69916d001f3e767661c6e1ee42553009d445d1cd840", size = 2207154, upload-time = "2025-09-17T16:33:29.457Z" }, + { url = "https://files.pythonhosted.org/packages/8f/6d/204f407df45600e2245b4a39860ed4ba32552330a0b3f5f160ae4cc30072/debugpy-1.8.17-cp311-cp311-manylinux_2_34_x86_64.whl", hash = "sha256:c6bdf134457ae0cac6fb68205776be635d31174eeac9541e1d0c062165c6461f", size = 3170322, upload-time = "2025-09-17T16:33:30.837Z" }, + { url = "https://files.pythonhosted.org/packages/f2/13/1b8f87d39cf83c6b713de2620c31205299e6065622e7dd37aff4808dd410/debugpy-1.8.17-cp311-cp311-win32.whl", hash = "sha256:e79a195f9e059edfe5d8bf6f3749b2599452d3e9380484cd261f6b7cd2c7c4da", size = 5155078, upload-time = "2025-09-17T16:33:33.331Z" }, + { url = "https://files.pythonhosted.org/packages/c2/c5/c012c60a2922cc91caa9675d0ddfbb14ba59e1e36228355f41cab6483469/debugpy-1.8.17-cp311-cp311-win_amd64.whl", hash = "sha256:b532282ad4eca958b1b2d7dbcb2b7218e02cb934165859b918e3b6ba7772d3f4", size = 5179011, upload-time = "2025-09-17T16:33:35.711Z" }, + { url = "https://files.pythonhosted.org/packages/08/2b/9d8e65beb2751876c82e1aceb32f328c43ec872711fa80257c7674f45650/debugpy-1.8.17-cp312-cp312-macosx_15_0_universal2.whl", hash = "sha256:f14467edef672195c6f6b8e27ce5005313cb5d03c9239059bc7182b60c176e2d", size = 2549522, upload-time = "2025-09-17T16:33:38.466Z" }, + { url = "https://files.pythonhosted.org/packages/b4/78/eb0d77f02971c05fca0eb7465b18058ba84bd957062f5eec82f941ac792a/debugpy-1.8.17-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:24693179ef9dfa20dca8605905a42b392be56d410c333af82f1c5dff807a64cc", size = 4309417, upload-time = "2025-09-17T16:33:41.299Z" }, + { url = "https://files.pythonhosted.org/packages/37/42/c40f1d8cc1fed1e75ea54298a382395b8b937d923fcf41ab0797a554f555/debugpy-1.8.17-cp312-cp312-win32.whl", hash = "sha256:6a4e9dacf2cbb60d2514ff7b04b4534b0139facbf2abdffe0639ddb6088e59cf", size = 5277130, upload-time = "2025-09-17T16:33:43.554Z" }, + { url = "https://files.pythonhosted.org/packages/72/22/84263b205baad32b81b36eac076de0cdbe09fe2d0637f5b32243dc7c925b/debugpy-1.8.17-cp312-cp312-win_amd64.whl", hash = "sha256:e8f8f61c518952fb15f74a302e068b48d9c4691768ade433e4adeea961993464", size = 5319053, upload-time = "2025-09-17T16:33:53.033Z" }, + { url = "https://files.pythonhosted.org/packages/50/76/597e5cb97d026274ba297af8d89138dfd9e695767ba0e0895edb20963f40/debugpy-1.8.17-cp313-cp313-macosx_15_0_universal2.whl", hash = "sha256:857c1dd5d70042502aef1c6d1c2801211f3ea7e56f75e9c335f434afb403e464", size = 2538386, upload-time = "2025-09-17T16:33:54.594Z" }, + { url = "https://files.pythonhosted.org/packages/5f/60/ce5c34fcdfec493701f9d1532dba95b21b2f6394147234dce21160bd923f/debugpy-1.8.17-cp313-cp313-manylinux_2_34_x86_64.whl", hash = "sha256:3bea3b0b12f3946e098cce9b43c3c46e317b567f79570c3f43f0b96d00788088", size = 4292100, upload-time = "2025-09-17T16:33:56.353Z" }, + { url = "https://files.pythonhosted.org/packages/e8/95/7873cf2146577ef71d2a20bf553f12df865922a6f87b9e8ee1df04f01785/debugpy-1.8.17-cp313-cp313-win32.whl", hash = "sha256:e34ee844c2f17b18556b5bbe59e1e2ff4e86a00282d2a46edab73fd7f18f4a83", size = 5277002, upload-time = "2025-09-17T16:33:58.231Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/18c79a1cee5ff539a94ec4aa290c1c069a5580fd5cfd2fb2e282f8e905da/debugpy-1.8.17-cp313-cp313-win_amd64.whl", hash = "sha256:6c5cd6f009ad4fca8e33e5238210dc1e5f42db07d4b6ab21ac7ffa904a196420", size = 5319047, upload-time = "2025-09-17T16:34:00.586Z" }, + { url = "https://files.pythonhosted.org/packages/b0/d0/89247ec250369fc76db477720a26b2fce7ba079ff1380e4ab4529d2fe233/debugpy-1.8.17-py2.py3-none-any.whl", hash = "sha256:60c7dca6571efe660ccb7a9508d73ca14b8796c4ed484c2002abba714226cfef", size = 5283210, upload-time = "2025-09-17T16:34:25.835Z" }, ] [[package]] @@ -777,6 +759,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/1f/10/5fe7a7778cc8a701373662f99393f443541353018d3cf2bf6c8f91b032d6/depinfo-2.2.0-py3-none-any.whl", hash = "sha256:3d9ba933e7a9d718b9915f75c844a38c5603cd3cdba1816ab95e0b148b100d8f", size = 24025, upload-time = "2022-09-07T16:27:49.813Z" }, ] +[[package]] +name = "deprecated" +version = "1.2.18" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wrapt" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/98/97/06afe62762c9a8a86af0cfb7bfdab22a43ad17138b07af5b1a58442690a2/deprecated-1.2.18.tar.gz", hash = "sha256:422b6f6d859da6f2ef57857761bfb392480502a64c3028ca9bbe86085d72115d", size = 2928744, upload-time = "2025-01-27T10:46:25.7Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6e/c6/ac0b6c1e2d138f1002bcf799d330bd6d85084fece321e662a14223794041/Deprecated-1.2.18-py2.py3-none-any.whl", hash = "sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec", size = 9998, upload-time = "2025-01-27T10:46:09.186Z" }, +] + [[package]] name = "dill" version = "0.4.0" @@ -871,35 +865,35 @@ wheels = [ [[package]] name = "fonttools" -version = "4.59.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0d/a5/fba25f9fbdab96e26dedcaeeba125e5f05a09043bf888e0305326e55685b/fonttools-4.59.2.tar.gz", hash = "sha256:e72c0749b06113f50bcb80332364c6be83a9582d6e3db3fe0b280f996dc2ef22", size = 3540889, upload-time = "2025-08-27T16:40:30.97Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f8/53/742fcd750ae0bdc74de4c0ff923111199cc2f90a4ee87aaddad505b6f477/fonttools-4.59.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:511946e8d7ea5c0d6c7a53c4cb3ee48eda9ab9797cd9bf5d95829a398400354f", size = 2774961, upload-time = "2025-08-27T16:38:47.536Z" }, - { url = "https://files.pythonhosted.org/packages/57/2a/976f5f9fa3b4dd911dc58d07358467bec20e813d933bc5d3db1a955dd456/fonttools-4.59.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8e5e2682cf7be766d84f462ba8828d01e00c8751a8e8e7ce12d7784ccb69a30d", size = 2344690, upload-time = "2025-08-27T16:38:49.723Z" }, - { url = "https://files.pythonhosted.org/packages/c1/8f/b7eefc274fcf370911e292e95565c8253b0b87c82a53919ab3c795a4f50e/fonttools-4.59.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5729e12a982dba3eeae650de48b06f3b9ddb51e9aee2fcaf195b7d09a96250e2", size = 5026910, upload-time = "2025-08-27T16:38:51.904Z" }, - { url = "https://files.pythonhosted.org/packages/69/95/864726eaa8f9d4e053d0c462e64d5830ec7c599cbdf1db9e40f25ca3972e/fonttools-4.59.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c52694eae5d652361d59ecdb5a2246bff7cff13b6367a12da8499e9df56d148d", size = 4971031, upload-time = "2025-08-27T16:38:53.676Z" }, - { url = "https://files.pythonhosted.org/packages/24/4c/b8c4735ebdea20696277c70c79e0de615dbe477834e5a7c2569aa1db4033/fonttools-4.59.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f1f1bbc23ba1312bd8959896f46f667753b90216852d2a8cfa2d07e0cb234144", size = 5006112, upload-time = "2025-08-27T16:38:55.69Z" }, - { url = "https://files.pythonhosted.org/packages/3b/23/f9ea29c292aa2fc1ea381b2e5621ac436d5e3e0a5dee24ffe5404e58eae8/fonttools-4.59.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1a1bfe5378962825dabe741720885e8b9ae9745ec7ecc4a5ec1f1ce59a6062bf", size = 5117671, upload-time = "2025-08-27T16:38:58.984Z" }, - { url = "https://files.pythonhosted.org/packages/ba/07/cfea304c555bf06e86071ff2a3916bc90f7c07ec85b23bab758d4908c33d/fonttools-4.59.2-cp311-cp311-win32.whl", hash = "sha256:e937790f3c2c18a1cbc7da101550a84319eb48023a715914477d2e7faeaba570", size = 2218157, upload-time = "2025-08-27T16:39:00.75Z" }, - { url = "https://files.pythonhosted.org/packages/d7/de/35d839aa69db737a3f9f3a45000ca24721834d40118652a5775d5eca8ebb/fonttools-4.59.2-cp311-cp311-win_amd64.whl", hash = "sha256:9836394e2f4ce5f9c0a7690ee93bd90aa1adc6b054f1a57b562c5d242c903104", size = 2265846, upload-time = "2025-08-27T16:39:02.453Z" }, - { url = "https://files.pythonhosted.org/packages/ba/3d/1f45db2df51e7bfa55492e8f23f383d372200be3a0ded4bf56a92753dd1f/fonttools-4.59.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:82906d002c349cad647a7634b004825a7335f8159d0d035ae89253b4abf6f3ea", size = 2769711, upload-time = "2025-08-27T16:39:04.423Z" }, - { url = "https://files.pythonhosted.org/packages/29/df/cd236ab32a8abfd11558f296e064424258db5edefd1279ffdbcfd4fd8b76/fonttools-4.59.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a10c1bd7644dc58f8862d8ba0cf9fb7fef0af01ea184ba6ce3f50ab7dfe74d5a", size = 2340225, upload-time = "2025-08-27T16:39:06.143Z" }, - { url = "https://files.pythonhosted.org/packages/98/12/b6f9f964fe6d4b4dd4406bcbd3328821c3de1f909ffc3ffa558fe72af48c/fonttools-4.59.2-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:738f31f23e0339785fd67652a94bc69ea49e413dfdb14dcb8c8ff383d249464e", size = 4912766, upload-time = "2025-08-27T16:39:08.138Z" }, - { url = "https://files.pythonhosted.org/packages/73/78/82bde2f2d2c306ef3909b927363170b83df96171f74e0ccb47ad344563cd/fonttools-4.59.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ec99f9bdfee9cdb4a9172f9e8fd578cce5feb231f598909e0aecf5418da4f25", size = 4955178, upload-time = "2025-08-27T16:39:10.094Z" }, - { url = "https://files.pythonhosted.org/packages/92/77/7de766afe2d31dda8ee46d7e479f35c7d48747e558961489a2d6e3a02bd4/fonttools-4.59.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0476ea74161322e08c7a982f83558a2b81b491509984523a1a540baf8611cc31", size = 4897898, upload-time = "2025-08-27T16:39:12.087Z" }, - { url = "https://files.pythonhosted.org/packages/c5/77/ce0e0b905d62a06415fda9f2b2e109a24a5db54a59502b769e9e297d2242/fonttools-4.59.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:95922a922daa1f77cc72611747c156cfb38030ead72436a2c551d30ecef519b9", size = 5049144, upload-time = "2025-08-27T16:39:13.84Z" }, - { url = "https://files.pythonhosted.org/packages/d9/ea/870d93aefd23fff2e07cbeebdc332527868422a433c64062c09d4d5e7fe6/fonttools-4.59.2-cp312-cp312-win32.whl", hash = "sha256:39ad9612c6a622726a6a130e8ab15794558591f999673f1ee7d2f3d30f6a3e1c", size = 2206473, upload-time = "2025-08-27T16:39:15.854Z" }, - { url = "https://files.pythonhosted.org/packages/61/c4/e44bad000c4a4bb2e9ca11491d266e857df98ab6d7428441b173f0fe2517/fonttools-4.59.2-cp312-cp312-win_amd64.whl", hash = "sha256:980fd7388e461b19a881d35013fec32c713ffea1fc37aef2f77d11f332dfd7da", size = 2254706, upload-time = "2025-08-27T16:39:17.893Z" }, - { url = "https://files.pythonhosted.org/packages/13/7b/d0d3b9431642947b5805201fbbbe938a47b70c76685ef1f0cb5f5d7140d6/fonttools-4.59.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:381bde13216ba09489864467f6bc0c57997bd729abfbb1ce6f807ba42c06cceb", size = 2761563, upload-time = "2025-08-27T16:39:20.286Z" }, - { url = "https://files.pythonhosted.org/packages/76/be/fc5fe58dd76af7127b769b68071dbc32d4b95adc8b58d1d28d42d93c90f2/fonttools-4.59.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f33839aa091f7eef4e9078f5b7ab1b8ea4b1d8a50aeaef9fdb3611bba80869ec", size = 2335671, upload-time = "2025-08-27T16:39:22.027Z" }, - { url = "https://files.pythonhosted.org/packages/f2/9f/bf231c2a3fac99d1d7f1d89c76594f158693f981a4aa02be406e9f036832/fonttools-4.59.2-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6235fc06bcbdb40186f483ba9d5d68f888ea68aa3c8dac347e05a7c54346fbc8", size = 4893967, upload-time = "2025-08-27T16:39:23.664Z" }, - { url = "https://files.pythonhosted.org/packages/26/a9/d46d2ad4fcb915198504d6727f83aa07f46764c64f425a861aa38756c9fd/fonttools-4.59.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:83ad6e5d06ef3a2884c4fa6384a20d6367b5cfe560e3b53b07c9dc65a7020e73", size = 4951986, upload-time = "2025-08-27T16:39:25.379Z" }, - { url = "https://files.pythonhosted.org/packages/07/90/1cc8d7dd8f707dfeeca472b82b898d3add0ebe85b1f645690dcd128ee63f/fonttools-4.59.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d029804c70fddf90be46ed5305c136cae15800a2300cb0f6bba96d48e770dde0", size = 4891630, upload-time = "2025-08-27T16:39:27.494Z" }, - { url = "https://files.pythonhosted.org/packages/d8/04/f0345b0d9fe67d65aa8d3f2d4cbf91d06f111bc7b8d802e65914eb06194d/fonttools-4.59.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:95807a3b5e78f2714acaa26a33bc2143005cc05c0217b322361a772e59f32b89", size = 5035116, upload-time = "2025-08-27T16:39:29.406Z" }, - { url = "https://files.pythonhosted.org/packages/d7/7d/5ba5eefffd243182fbd067cdbfeb12addd4e5aec45011b724c98a344ea33/fonttools-4.59.2-cp313-cp313-win32.whl", hash = "sha256:b3ebda00c3bb8f32a740b72ec38537d54c7c09f383a4cfefb0b315860f825b08", size = 2204907, upload-time = "2025-08-27T16:39:31.42Z" }, - { url = "https://files.pythonhosted.org/packages/ea/a9/be7219fc64a6026cc0aded17fa3720f9277001c185434230bd351bf678e6/fonttools-4.59.2-cp313-cp313-win_amd64.whl", hash = "sha256:a72155928d7053bbde499d32a9c77d3f0f3d29ae72b5a121752481bcbd71e50f", size = 2253742, upload-time = "2025-08-27T16:39:33.079Z" }, - { url = "https://files.pythonhosted.org/packages/65/a4/d2f7be3c86708912c02571db0b550121caab8cd88a3c0aacb9cfa15ea66e/fonttools-4.59.2-py3-none-any.whl", hash = "sha256:8bd0f759020e87bb5d323e6283914d9bf4ae35a7307dafb2cbd1e379e720ad37", size = 1132315, upload-time = "2025-08-27T16:40:28.984Z" }, +version = "4.60.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4b/42/97a13e47a1e51a5a7142475bbcf5107fe3a68fc34aef331c897d5fb98ad0/fonttools-4.60.1.tar.gz", hash = "sha256:ef00af0439ebfee806b25f24c8f92109157ff3fac5731dc7867957812e87b8d9", size = 3559823, upload-time = "2025-09-29T21:13:27.129Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ea/85/639aa9bface1537e0fb0f643690672dde0695a5bbbc90736bc571b0b1941/fonttools-4.60.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7b4c32e232a71f63a5d00259ca3d88345ce2a43295bb049d21061f338124246f", size = 2831872, upload-time = "2025-09-29T21:11:20.329Z" }, + { url = "https://files.pythonhosted.org/packages/6b/47/3c63158459c95093be9618794acb1067b3f4d30dcc5c3e8114b70e67a092/fonttools-4.60.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3630e86c484263eaac71d117085d509cbcf7b18f677906824e4bace598fb70d2", size = 2356990, upload-time = "2025-09-29T21:11:22.754Z" }, + { url = "https://files.pythonhosted.org/packages/94/dd/1934b537c86fcf99f9761823f1fc37a98fbd54568e8e613f29a90fed95a9/fonttools-4.60.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5c1015318e4fec75dd4943ad5f6a206d9727adf97410d58b7e32ab644a807914", size = 5042189, upload-time = "2025-09-29T21:11:25.061Z" }, + { url = "https://files.pythonhosted.org/packages/d2/d2/9f4e4c4374dd1daa8367784e1bd910f18ba886db1d6b825b12edf6db3edc/fonttools-4.60.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e6c58beb17380f7c2ea181ea11e7db8c0ceb474c9dd45f48e71e2cb577d146a1", size = 4978683, upload-time = "2025-09-29T21:11:27.693Z" }, + { url = "https://files.pythonhosted.org/packages/cc/c4/0fb2dfd1ecbe9a07954cc13414713ed1eab17b1c0214ef07fc93df234a47/fonttools-4.60.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ec3681a0cb34c255d76dd9d865a55f260164adb9fa02628415cdc2d43ee2c05d", size = 5021372, upload-time = "2025-09-29T21:11:30.257Z" }, + { url = "https://files.pythonhosted.org/packages/0c/d5/495fc7ae2fab20223cc87179a8f50f40f9a6f821f271ba8301ae12bb580f/fonttools-4.60.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f4b5c37a5f40e4d733d3bbaaef082149bee5a5ea3156a785ff64d949bd1353fa", size = 5132562, upload-time = "2025-09-29T21:11:32.737Z" }, + { url = "https://files.pythonhosted.org/packages/bc/fa/021dab618526323c744e0206b3f5c8596a2e7ae9aa38db5948a131123e83/fonttools-4.60.1-cp311-cp311-win32.whl", hash = "sha256:398447f3d8c0c786cbf1209711e79080a40761eb44b27cdafffb48f52bcec258", size = 2230288, upload-time = "2025-09-29T21:11:35.015Z" }, + { url = "https://files.pythonhosted.org/packages/bb/78/0e1a6d22b427579ea5c8273e1c07def2f325b977faaf60bb7ddc01456cb1/fonttools-4.60.1-cp311-cp311-win_amd64.whl", hash = "sha256:d066ea419f719ed87bc2c99a4a4bfd77c2e5949cb724588b9dd58f3fd90b92bf", size = 2278184, upload-time = "2025-09-29T21:11:37.434Z" }, + { url = "https://files.pythonhosted.org/packages/e3/f7/a10b101b7a6f8836a5adb47f2791f2075d044a6ca123f35985c42edc82d8/fonttools-4.60.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:7b0c6d57ab00dae9529f3faf187f2254ea0aa1e04215cf2f1a8ec277c96661bc", size = 2832953, upload-time = "2025-09-29T21:11:39.616Z" }, + { url = "https://files.pythonhosted.org/packages/ed/fe/7bd094b59c926acf2304d2151354ddbeb74b94812f3dc943c231db09cb41/fonttools-4.60.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:839565cbf14645952d933853e8ade66a463684ed6ed6c9345d0faf1f0e868877", size = 2352706, upload-time = "2025-09-29T21:11:41.826Z" }, + { url = "https://files.pythonhosted.org/packages/c0/ca/4bb48a26ed95a1e7eba175535fe5805887682140ee0a0d10a88e1de84208/fonttools-4.60.1-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8177ec9676ea6e1793c8a084a90b65a9f778771998eb919d05db6d4b1c0b114c", size = 4923716, upload-time = "2025-09-29T21:11:43.893Z" }, + { url = "https://files.pythonhosted.org/packages/b8/9f/2cb82999f686c1d1ddf06f6ae1a9117a880adbec113611cc9d22b2fdd465/fonttools-4.60.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:996a4d1834524adbb423385d5a629b868ef9d774670856c63c9a0408a3063401", size = 4968175, upload-time = "2025-09-29T21:11:46.439Z" }, + { url = "https://files.pythonhosted.org/packages/18/79/be569699e37d166b78e6218f2cde8c550204f2505038cdd83b42edc469b9/fonttools-4.60.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a46b2f450bc79e06ef3b6394f0c68660529ed51692606ad7f953fc2e448bc903", size = 4911031, upload-time = "2025-09-29T21:11:48.977Z" }, + { url = "https://files.pythonhosted.org/packages/cc/9f/89411cc116effaec5260ad519162f64f9c150e5522a27cbb05eb62d0c05b/fonttools-4.60.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6ec722ee589e89a89f5b7574f5c45604030aa6ae24cb2c751e2707193b466fed", size = 5062966, upload-time = "2025-09-29T21:11:54.344Z" }, + { url = "https://files.pythonhosted.org/packages/62/a1/f888221934b5731d46cb9991c7a71f30cb1f97c0ef5fcf37f8da8fce6c8e/fonttools-4.60.1-cp312-cp312-win32.whl", hash = "sha256:b2cf105cee600d2de04ca3cfa1f74f1127f8455b71dbad02b9da6ec266e116d6", size = 2218750, upload-time = "2025-09-29T21:11:56.601Z" }, + { url = "https://files.pythonhosted.org/packages/88/8f/a55b5550cd33cd1028601df41acd057d4be20efa5c958f417b0c0613924d/fonttools-4.60.1-cp312-cp312-win_amd64.whl", hash = "sha256:992775c9fbe2cf794786fa0ffca7f09f564ba3499b8fe9f2f80bd7197db60383", size = 2267026, upload-time = "2025-09-29T21:11:58.852Z" }, + { url = "https://files.pythonhosted.org/packages/7c/5b/cdd2c612277b7ac7ec8c0c9bc41812c43dc7b2d5f2b0897e15fdf5a1f915/fonttools-4.60.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6f68576bb4bbf6060c7ab047b1574a1ebe5c50a17de62830079967b211059ebb", size = 2825777, upload-time = "2025-09-29T21:12:01.22Z" }, + { url = "https://files.pythonhosted.org/packages/d6/8a/de9cc0540f542963ba5e8f3a1f6ad48fa211badc3177783b9d5cadf79b5d/fonttools-4.60.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:eedacb5c5d22b7097482fa834bda0dafa3d914a4e829ec83cdea2a01f8c813c4", size = 2348080, upload-time = "2025-09-29T21:12:03.785Z" }, + { url = "https://files.pythonhosted.org/packages/2d/8b/371ab3cec97ee3fe1126b3406b7abd60c8fec8975fd79a3c75cdea0c3d83/fonttools-4.60.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b33a7884fabd72bdf5f910d0cf46be50dce86a0362a65cfc746a4168c67eb96c", size = 4903082, upload-time = "2025-09-29T21:12:06.382Z" }, + { url = "https://files.pythonhosted.org/packages/04/05/06b1455e4bc653fcb2117ac3ef5fa3a8a14919b93c60742d04440605d058/fonttools-4.60.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2409d5fb7b55fd70f715e6d34e7a6e4f7511b8ad29a49d6df225ee76da76dd77", size = 4960125, upload-time = "2025-09-29T21:12:09.314Z" }, + { url = "https://files.pythonhosted.org/packages/8e/37/f3b840fcb2666f6cb97038793606bdd83488dca2d0b0fc542ccc20afa668/fonttools-4.60.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c8651e0d4b3bdeda6602b85fdc2abbefc1b41e573ecb37b6779c4ca50753a199", size = 4901454, upload-time = "2025-09-29T21:12:11.931Z" }, + { url = "https://files.pythonhosted.org/packages/fd/9e/eb76f77e82f8d4a46420aadff12cec6237751b0fb9ef1de373186dcffb5f/fonttools-4.60.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:145daa14bf24824b677b9357c5e44fd8895c2a8f53596e1b9ea3496081dc692c", size = 5044495, upload-time = "2025-09-29T21:12:15.241Z" }, + { url = "https://files.pythonhosted.org/packages/f8/b3/cede8f8235d42ff7ae891bae8d619d02c8ac9fd0cfc450c5927a6200c70d/fonttools-4.60.1-cp313-cp313-win32.whl", hash = "sha256:2299df884c11162617a66b7c316957d74a18e3758c0274762d2cc87df7bc0272", size = 2217028, upload-time = "2025-09-29T21:12:17.96Z" }, + { url = "https://files.pythonhosted.org/packages/75/4d/b022c1577807ce8b31ffe055306ec13a866f2337ecee96e75b24b9b753ea/fonttools-4.60.1-cp313-cp313-win_amd64.whl", hash = "sha256:a3db56f153bd4c5c2b619ab02c5db5192e222150ce5a1bc10f16164714bc39ac", size = 2266200, upload-time = "2025-09-29T21:12:20.14Z" }, + { url = "https://files.pythonhosted.org/packages/c7/93/0dd45cd283c32dea1545151d8c3637b4b8c53cdb3a625aeb2885b184d74d/fonttools-4.60.1-py3-none-any.whl", hash = "sha256:906306ac7afe2156fcf0042173d6ebbb05416af70f6b370967b47f8f00103bbb", size = 1143175, upload-time = "2025-09-29T21:13:24.134Z" }, ] [[package]] @@ -1031,11 +1025,11 @@ wheels = [ [[package]] name = "identify" -version = "2.6.13" +version = "2.6.15" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/82/ca/ffbabe3635bb839aa36b3a893c91a9b0d368cb4d8073e03a12896970af82/identify-2.6.13.tar.gz", hash = "sha256:da8d6c828e773620e13bfa86ea601c5a5310ba4bcd65edf378198b56a1f9fb32", size = 99243, upload-time = "2025-08-09T19:35:00.6Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ff/e7/685de97986c916a6d93b3876139e00eef26ad5bbbd61925d670ae8013449/identify-2.6.15.tar.gz", hash = "sha256:e4f4864b96c6557ef2a1e1c951771838f4edc9df3a72ec7118b338801b11c7bf", size = 99311, upload-time = "2025-10-02T17:43:40.631Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/ce/461b60a3ee109518c055953729bf9ed089a04db895d47e95444071dcdef2/identify-2.6.13-py2.py3-none-any.whl", hash = "sha256:60381139b3ae39447482ecc406944190f690d4a2997f2584062089848361b33b", size = 99153, upload-time = "2025-08-09T19:34:59.1Z" }, + { url = "https://files.pythonhosted.org/packages/0f/1c/e5fd8f973d4f375adb21565739498e2e9a1e54c858a97b9a8ccfdc81da9b/identify-2.6.15-py2.py3-none-any.whl", hash = "sha256:1181ef7608e00704db228516541eb83a88a9f94433a8c80bb9b5bd54b1d81757", size = 99183, upload-time = "2025-10-02T17:43:39.137Z" }, ] [[package]] @@ -1047,18 +1041,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, ] -[[package]] -name = "importlib-metadata" -version = "8.7.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "zipp" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/76/66/650a33bd90f786193e4de4b3ad86ea60b53c89b669a5c7be931fac31cdb0/importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000", size = 56641, upload-time = "2025-04-27T15:29:01.736Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/20/b0/36bd937216ec521246249be3bf9855081de4c5e06a0c9b4219dbeda50373/importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd", size = 27656, upload-time = "2025-04-27T15:29:00.214Z" }, -] - [[package]] name = "importlib-resources" version = "6.5.2" @@ -1112,7 +1094,7 @@ wheels = [ [[package]] name = "ipython" -version = "9.5.0" +version = "9.6.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -1127,9 +1109,9 @@ dependencies = [ { name = "traitlets" }, { name = "typing-extensions", marker = "python_full_version < '3.12'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6e/71/a86262bf5a68bf211bcc71fe302af7e05f18a2852fdc610a854d20d085e6/ipython-9.5.0.tar.gz", hash = "sha256:129c44b941fe6d9b82d36fc7a7c18127ddb1d6f02f78f867f402e2e3adde3113", size = 4389137, upload-time = "2025-08-29T12:15:21.519Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2a/34/29b18c62e39ee2f7a6a3bba7efd952729d8aadd45ca17efc34453b717665/ipython-9.6.0.tar.gz", hash = "sha256:5603d6d5d356378be5043e69441a072b50a5b33b4503428c77b04cb8ce7bc731", size = 4396932, upload-time = "2025-09-29T10:55:53.948Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/08/2a/5628a99d04acb2d2f2e749cdf4ea571d2575e898df0528a090948018b726/ipython-9.5.0-py3-none-any.whl", hash = "sha256:88369ffa1d5817d609120daa523a6da06d02518e582347c29f8451732a9c5e72", size = 612426, upload-time = "2025-08-29T12:15:18.866Z" }, + { url = "https://files.pythonhosted.org/packages/48/c5/d5e07995077e48220269c28a221e168c91123ad5ceee44d548f54a057fc0/ipython-9.6.0-py3-none-any.whl", hash = "sha256:5f77efafc886d2f023442479b8149e7d86547ad0a979e9da9f045d252f648196", size = 616170, upload-time = "2025-09-29T10:55:47.676Z" }, ] [[package]] @@ -1237,14 +1219,14 @@ format-nongpl = [ [[package]] name = "jsonschema-specifications" -version = "2025.4.1" +version = "2025.9.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "referencing" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bf/ce/46fbd9c8119cfc3581ee5643ea49464d168028cfb5caff5fc0596d0cf914/jsonschema_specifications-2025.4.1.tar.gz", hash = "sha256:630159c9f4dbea161a6a2205c3011cc4f18ff381b189fff48bb39b9bf26ae608", size = 15513, upload-time = "2025-04-23T12:34:07.418Z" } +sdist = { url = "https://files.pythonhosted.org/packages/19/74/a633ee74eb36c44aa6d1095e7cc5569bebf04342ee146178e2d36600708b/jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d", size = 32855, upload-time = "2025-09-08T01:34:59.186Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/01/0e/b27cdbaccf30b890c40ed1da9fd4a3593a5cf94dae54fb34f8a4b74fcd3f/jsonschema_specifications-2025.4.1-py3-none-any.whl", hash = "sha256:4653bffbd6584f7de83a67e0d620ef16900b390ddc7939d56684d6c81e33f1af", size = 18437, upload-time = "2025-04-23T12:34:05.422Z" }, + { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" }, ] [[package]] @@ -1353,7 +1335,7 @@ wheels = [ [[package]] name = "jupyterlab" -version = "4.4.6" +version = "4.4.9" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "async-lru" }, @@ -1370,9 +1352,9 @@ dependencies = [ { name = "tornado" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1e/5c/14f0852233d60d30bf0f22a817d6c20ac555d73526cc915274f97c07a2b9/jupyterlab-4.4.6.tar.gz", hash = "sha256:e0b720ff5392846bdbc01745f32f29f4d001c071a4bff94d8b516ba89b5a4157", size = 23040936, upload-time = "2025-08-15T11:44:15.915Z" } +sdist = { url = "https://files.pythonhosted.org/packages/45/b2/7dad2d0049a904d17c070226a4f78f81905f93bfe09503722d210ccf9335/jupyterlab-4.4.9.tar.gz", hash = "sha256:ea55aca8269909016d5fde2dc09b97128bc931230183fe7e2920ede5154ad9c2", size = 22966654, upload-time = "2025-09-26T17:28:20.158Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/53/38/6182d63f39428821e705e86fba61704fc69769a24ca5a9578c2c04986c9a/jupyterlab-4.4.6-py3-none-any.whl", hash = "sha256:e877e930f46dde2e3ee9da36a935c6cd4fdb15aa7440519d0fde696f9fadb833", size = 12268564, upload-time = "2025-08-15T11:44:11.42Z" }, + { url = "https://files.pythonhosted.org/packages/1f/fd/ac0979ebd1b1975c266c99b96930b0a66609c3f6e5d76979ca6eb3073896/jupyterlab-4.4.9-py3-none-any.whl", hash = "sha256:394c902827350c017430a8370b9f40c03c098773084bc53930145c146d3d2cb2", size = 12292552, upload-time = "2025-09-26T17:28:15.663Z" }, ] [[package]] @@ -1404,17 +1386,18 @@ wheels = [ [[package]] name = "kaleido" -version = "1.0.0" +version = "1.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "choreographer" }, { name = "logistro" }, { name = "orjson" }, { name = "packaging" }, + { name = "pytest-timeout" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/15/dc/fd2d955884f45f852152d44f5ecf79de3cb58da0f995b6f6f9acfc80dd94/kaleido-1.0.0.tar.gz", hash = "sha256:502d8ba64737924efaf5e94c2736745bcc7c926e6cc535838be36c0fc06330bd", size = 49400, upload-time = "2025-06-19T15:50:39.357Z" } +sdist = { url = "https://files.pythonhosted.org/packages/49/0c/3624462629aeb9f5bb043583848ce300b4315e8249b393c494c84149b953/kaleido-1.1.0.tar.gz", hash = "sha256:5747703a56d4c034efa69abea4a9c2bfe8ef516ba848e0ec485c65b3b0ab52b6", size = 62044, upload-time = "2025-09-10T19:31:13.925Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/28/0e/853df00cac4823eaa8f35114d0d0ad1e2ec6b8243ce4acf5f8ac5235c517/kaleido-1.0.0-py3-none-any.whl", hash = "sha256:a7e8bd95648378d2746f6c86084d419d15f95b1ec7bb0ec810289b7feb25b18d", size = 51479, upload-time = "2025-06-19T15:50:37.884Z" }, + { url = "https://files.pythonhosted.org/packages/5a/bf/10b009e3b96a803f25af126951bc167402354d765006a94d11ba46a2f667/kaleido-1.1.0-py3-none-any.whl", hash = "sha256:839ed2357b89dd2f93c478960f41c401fe4038d404ae33e2fdbde028c18d7430", size = 66347, upload-time = "2025-09-10T19:31:12.869Z" }, ] [[package]] @@ -1483,11 +1466,11 @@ wheels = [ [[package]] name = "lark" -version = "1.2.2" +version = "1.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/60/bc7622aefb2aee1c0b4ba23c1446d3e30225c8770b38d7aedbfb65ca9d5a/lark-1.2.2.tar.gz", hash = "sha256:ca807d0162cd16cef15a8feecb862d7319e7a09bdb13aef927968e45040fed80", size = 252132, upload-time = "2024-08-13T19:49:00.652Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/37/a13baf0135f348af608c667633cbe5d13aa2c5c15a56ae9ad3e6cba45ae3/lark-1.3.0.tar.gz", hash = "sha256:9a3839d0ca5e1faf7cfa3460e420e859b66bcbde05b634e73c369c8244c5fa48", size = 259551, upload-time = "2025-09-22T13:45:05.072Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/00/d90b10b962b4277f5e64a78b6609968859ff86889f5b898c1a778c06ec00/lark-1.2.2-py3-none-any.whl", hash = "sha256:c2276486b02f0f1b90be155f2c8ba4a8e194d42775786db622faccd652d8e80c", size = 111036, upload-time = "2024-08-13T19:48:58.603Z" }, + { url = "https://files.pythonhosted.org/packages/a8/3e/1c6b43277de64fc3c0333b0e72ab7b52ddaaea205210d60d9b9f83c3d0c7/lark-1.3.0-py3-none-any.whl", hash = "sha256:80661f261fb2584a9828a097a2432efd575af27d20be0fd35d17f0fe37253831", size = 113002, upload-time = "2025-09-22T13:45:03.747Z" }, ] [[package]] @@ -1501,25 +1484,25 @@ wheels = [ [[package]] name = "llvmlite" -version = "0.44.0" +version = "0.45.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/89/6a/95a3d3610d5c75293d5dbbb2a76480d5d4eeba641557b69fe90af6c5b84e/llvmlite-0.44.0.tar.gz", hash = "sha256:07667d66a5d150abed9157ab6c0b9393c9356f229784a4385c02f99e94fc94d4", size = 171880, upload-time = "2025-01-20T11:14:41.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/99/8d/5baf1cef7f9c084fb35a8afbde88074f0d6a727bc63ef764fe0e7543ba40/llvmlite-0.45.1.tar.gz", hash = "sha256:09430bb9d0bb58fc45a45a57c7eae912850bedc095cd0810a57de109c69e1c32", size = 185600, upload-time = "2025-10-01T17:59:52.046Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b5/e2/86b245397052386595ad726f9742e5223d7aea999b18c518a50e96c3aca4/llvmlite-0.44.0-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:eed7d5f29136bda63b6d7804c279e2b72e08c952b7c5df61f45db408e0ee52f3", size = 28132305, upload-time = "2025-01-20T11:12:53.936Z" }, - { url = "https://files.pythonhosted.org/packages/ff/ec/506902dc6870249fbe2466d9cf66d531265d0f3a1157213c8f986250c033/llvmlite-0.44.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ace564d9fa44bb91eb6e6d8e7754977783c68e90a471ea7ce913bff30bd62427", size = 26201090, upload-time = "2025-01-20T11:12:59.847Z" }, - { url = "https://files.pythonhosted.org/packages/99/fe/d030f1849ebb1f394bb3f7adad5e729b634fb100515594aca25c354ffc62/llvmlite-0.44.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5d22c3bfc842668168a786af4205ec8e3ad29fb1bc03fd11fd48460d0df64c1", size = 42361858, upload-time = "2025-01-20T11:13:07.623Z" }, - { url = "https://files.pythonhosted.org/packages/d7/7a/ce6174664b9077fc673d172e4c888cb0b128e707e306bc33fff8c2035f0d/llvmlite-0.44.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f01a394e9c9b7b1d4e63c327b096d10f6f0ed149ef53d38a09b3749dcf8c9610", size = 41184200, upload-time = "2025-01-20T11:13:20.058Z" }, - { url = "https://files.pythonhosted.org/packages/5f/c6/258801143975a6d09a373f2641237992496e15567b907a4d401839d671b8/llvmlite-0.44.0-cp311-cp311-win_amd64.whl", hash = "sha256:d8489634d43c20cd0ad71330dde1d5bc7b9966937a263ff1ec1cebb90dc50955", size = 30331193, upload-time = "2025-01-20T11:13:26.976Z" }, - { url = "https://files.pythonhosted.org/packages/15/86/e3c3195b92e6e492458f16d233e58a1a812aa2bfbef9bdd0fbafcec85c60/llvmlite-0.44.0-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:1d671a56acf725bf1b531d5ef76b86660a5ab8ef19bb6a46064a705c6ca80aad", size = 28132297, upload-time = "2025-01-20T11:13:32.57Z" }, - { url = "https://files.pythonhosted.org/packages/d6/53/373b6b8be67b9221d12b24125fd0ec56b1078b660eeae266ec388a6ac9a0/llvmlite-0.44.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f79a728e0435493611c9f405168682bb75ffd1fbe6fc360733b850c80a026db", size = 26201105, upload-time = "2025-01-20T11:13:38.744Z" }, - { url = "https://files.pythonhosted.org/packages/cb/da/8341fd3056419441286c8e26bf436923021005ece0bff5f41906476ae514/llvmlite-0.44.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0143a5ef336da14deaa8ec26c5449ad5b6a2b564df82fcef4be040b9cacfea9", size = 42361901, upload-time = "2025-01-20T11:13:46.711Z" }, - { url = "https://files.pythonhosted.org/packages/53/ad/d79349dc07b8a395a99153d7ce8b01d6fcdc9f8231355a5df55ded649b61/llvmlite-0.44.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d752f89e31b66db6f8da06df8b39f9b91e78c5feea1bf9e8c1fba1d1c24c065d", size = 41184247, upload-time = "2025-01-20T11:13:56.159Z" }, - { url = "https://files.pythonhosted.org/packages/e2/3b/a9a17366af80127bd09decbe2a54d8974b6d8b274b39bf47fbaedeec6307/llvmlite-0.44.0-cp312-cp312-win_amd64.whl", hash = "sha256:eae7e2d4ca8f88f89d315b48c6b741dcb925d6a1042da694aa16ab3dd4cbd3a1", size = 30332380, upload-time = "2025-01-20T11:14:02.442Z" }, - { url = "https://files.pythonhosted.org/packages/89/24/4c0ca705a717514c2092b18476e7a12c74d34d875e05e4d742618ebbf449/llvmlite-0.44.0-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:319bddd44e5f71ae2689859b7203080716448a3cd1128fb144fe5c055219d516", size = 28132306, upload-time = "2025-01-20T11:14:09.035Z" }, - { url = "https://files.pythonhosted.org/packages/01/cf/1dd5a60ba6aee7122ab9243fd614abcf22f36b0437cbbe1ccf1e3391461c/llvmlite-0.44.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9c58867118bad04a0bb22a2e0068c693719658105e40009ffe95c7000fcde88e", size = 26201090, upload-time = "2025-01-20T11:14:15.401Z" }, - { url = "https://files.pythonhosted.org/packages/d2/1b/656f5a357de7135a3777bd735cc7c9b8f23b4d37465505bd0eaf4be9befe/llvmlite-0.44.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46224058b13c96af1365290bdfebe9a6264ae62fb79b2b55693deed11657a8bf", size = 42361904, upload-time = "2025-01-20T11:14:22.949Z" }, - { url = "https://files.pythonhosted.org/packages/d8/e1/12c5f20cb9168fb3464a34310411d5ad86e4163c8ff2d14a2b57e5cc6bac/llvmlite-0.44.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa0097052c32bf721a4efc03bd109d335dfa57d9bffb3d4c24cc680711b8b4fc", size = 41184245, upload-time = "2025-01-20T11:14:31.731Z" }, - { url = "https://files.pythonhosted.org/packages/d0/81/e66fc86539293282fd9cb7c9417438e897f369e79ffb62e1ae5e5154d4dd/llvmlite-0.44.0-cp313-cp313-win_amd64.whl", hash = "sha256:2fb7c4f2fb86cbae6dca3db9ab203eeea0e22d73b99bc2341cdf9de93612e930", size = 30331193, upload-time = "2025-01-20T11:14:38.578Z" }, + { url = "https://files.pythonhosted.org/packages/04/ad/9bdc87b2eb34642c1cfe6bcb4f5db64c21f91f26b010f263e7467e7536a3/llvmlite-0.45.1-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:60f92868d5d3af30b4239b50e1717cb4e4e54f6ac1c361a27903b318d0f07f42", size = 43043526, upload-time = "2025-10-01T18:03:15.051Z" }, + { url = "https://files.pythonhosted.org/packages/a5/ea/c25c6382f452a943b4082da5e8c1665ce29a62884e2ec80608533e8e82d5/llvmlite-0.45.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:98baab513e19beb210f1ef39066288784839a44cd504e24fff5d17f1b3cf0860", size = 37253118, upload-time = "2025-10-01T18:04:06.783Z" }, + { url = "https://files.pythonhosted.org/packages/fe/af/85fc237de98b181dbbe8647324331238d6c52a3554327ccdc83ced28efba/llvmlite-0.45.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3adc2355694d6a6fbcc024d59bb756677e7de506037c878022d7b877e7613a36", size = 56288209, upload-time = "2025-10-01T18:01:00.168Z" }, + { url = "https://files.pythonhosted.org/packages/0a/df/3daf95302ff49beff4230065e3178cd40e71294968e8d55baf4a9e560814/llvmlite-0.45.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2f3377a6db40f563058c9515dedcc8a3e562d8693a106a28f2ddccf2c8fcf6ca", size = 55140958, upload-time = "2025-10-01T18:02:11.199Z" }, + { url = "https://files.pythonhosted.org/packages/a4/56/4c0d503fe03bac820ecdeb14590cf9a248e120f483bcd5c009f2534f23f0/llvmlite-0.45.1-cp311-cp311-win_amd64.whl", hash = "sha256:f9c272682d91e0d57f2a76c6d9ebdfccc603a01828cdbe3d15273bdca0c3363a", size = 38132232, upload-time = "2025-10-01T18:04:52.181Z" }, + { url = "https://files.pythonhosted.org/packages/e2/7c/82cbd5c656e8991bcc110c69d05913be2229302a92acb96109e166ae31fb/llvmlite-0.45.1-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:28e763aba92fe9c72296911e040231d486447c01d4f90027c8e893d89d49b20e", size = 43043524, upload-time = "2025-10-01T18:03:30.666Z" }, + { url = "https://files.pythonhosted.org/packages/9d/bc/5314005bb2c7ee9f33102c6456c18cc81745d7055155d1218f1624463774/llvmlite-0.45.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1a53f4b74ee9fd30cb3d27d904dadece67a7575198bd80e687ee76474620735f", size = 37253123, upload-time = "2025-10-01T18:04:18.177Z" }, + { url = "https://files.pythonhosted.org/packages/96/76/0f7154952f037cb320b83e1c952ec4a19d5d689cf7d27cb8a26887d7bbc1/llvmlite-0.45.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5b3796b1b1e1c14dcae34285d2f4ea488402fbd2c400ccf7137603ca3800864f", size = 56288211, upload-time = "2025-10-01T18:01:24.079Z" }, + { url = "https://files.pythonhosted.org/packages/00/b1/0b581942be2683ceb6862d558979e87387e14ad65a1e4db0e7dd671fa315/llvmlite-0.45.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:779e2f2ceefef0f4368548685f0b4adde34e5f4b457e90391f570a10b348d433", size = 55140958, upload-time = "2025-10-01T18:02:30.482Z" }, + { url = "https://files.pythonhosted.org/packages/33/94/9ba4ebcf4d541a325fd8098ddc073b663af75cc8b065b6059848f7d4dce7/llvmlite-0.45.1-cp312-cp312-win_amd64.whl", hash = "sha256:9e6c9949baf25d9aa9cd7cf0f6d011b9ca660dd17f5ba2b23bdbdb77cc86b116", size = 38132231, upload-time = "2025-10-01T18:05:03.664Z" }, + { url = "https://files.pythonhosted.org/packages/1d/e2/c185bb7e88514d5025f93c6c4092f6120c6cea8fe938974ec9860fb03bbb/llvmlite-0.45.1-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:d9ea9e6f17569a4253515cc01dade70aba536476e3d750b2e18d81d7e670eb15", size = 43043524, upload-time = "2025-10-01T18:03:43.249Z" }, + { url = "https://files.pythonhosted.org/packages/09/b8/b5437b9ecb2064e89ccf67dccae0d02cd38911705112dd0dcbfa9cd9a9de/llvmlite-0.45.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:c9f3cadee1630ce4ac18ea38adebf2a4f57a89bd2740ce83746876797f6e0bfb", size = 37253121, upload-time = "2025-10-01T18:04:30.557Z" }, + { url = "https://files.pythonhosted.org/packages/f7/97/ad1a907c0173a90dd4df7228f24a3ec61058bc1a9ff8a0caec20a0cc622e/llvmlite-0.45.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:57c48bf2e1083eedbc9406fb83c4e6483017879714916fe8be8a72a9672c995a", size = 56288210, upload-time = "2025-10-01T18:01:40.26Z" }, + { url = "https://files.pythonhosted.org/packages/32/d8/c99c8ac7a326e9735401ead3116f7685a7ec652691aeb2615aa732b1fc4a/llvmlite-0.45.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3aa3dfceda4219ae39cf18806c60eeb518c1680ff834b8b311bd784160b9ce40", size = 55140957, upload-time = "2025-10-01T18:02:46.244Z" }, + { url = "https://files.pythonhosted.org/packages/09/56/ed35668130e32dbfad2eb37356793b0a95f23494ab5be7d9bf5cb75850ee/llvmlite-0.45.1-cp313-cp313-win_amd64.whl", hash = "sha256:080e6f8d0778a8239cd47686d402cb66eb165e421efa9391366a9b7e5810a38b", size = 38132232, upload-time = "2025-10-01T18:05:14.477Z" }, ] [[package]] @@ -1558,50 +1541,54 @@ wheels = [ [[package]] name = "markupsafe" -version = "3.0.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537, upload-time = "2024-10-18T15:21:54.129Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6b/28/bbf83e3f76936960b850435576dd5e67034e200469571be53f69174a2dfd/MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", size = 14353, upload-time = "2024-10-18T15:21:02.187Z" }, - { url = "https://files.pythonhosted.org/packages/6c/30/316d194b093cde57d448a4c3209f22e3046c5bb2fb0820b118292b334be7/MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", size = 12392, upload-time = "2024-10-18T15:21:02.941Z" }, - { url = "https://files.pythonhosted.org/packages/f2/96/9cdafba8445d3a53cae530aaf83c38ec64c4d5427d975c974084af5bc5d2/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", size = 23984, upload-time = "2024-10-18T15:21:03.953Z" }, - { url = "https://files.pythonhosted.org/packages/f1/a4/aefb044a2cd8d7334c8a47d3fb2c9f328ac48cb349468cc31c20b539305f/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", size = 23120, upload-time = "2024-10-18T15:21:06.495Z" }, - { url = "https://files.pythonhosted.org/packages/8d/21/5e4851379f88f3fad1de30361db501300d4f07bcad047d3cb0449fc51f8c/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", size = 23032, upload-time = "2024-10-18T15:21:07.295Z" }, - { url = "https://files.pythonhosted.org/packages/00/7b/e92c64e079b2d0d7ddf69899c98842f3f9a60a1ae72657c89ce2655c999d/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", size = 24057, upload-time = "2024-10-18T15:21:08.073Z" }, - { url = "https://files.pythonhosted.org/packages/f9/ac/46f960ca323037caa0a10662ef97d0a4728e890334fc156b9f9e52bcc4ca/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", size = 23359, upload-time = "2024-10-18T15:21:09.318Z" }, - { url = "https://files.pythonhosted.org/packages/69/84/83439e16197337b8b14b6a5b9c2105fff81d42c2a7c5b58ac7b62ee2c3b1/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", size = 23306, upload-time = "2024-10-18T15:21:10.185Z" }, - { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094, upload-time = "2024-10-18T15:21:11.005Z" }, - { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521, upload-time = "2024-10-18T15:21:12.911Z" }, - { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274, upload-time = "2024-10-18T15:21:13.777Z" }, - { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348, upload-time = "2024-10-18T15:21:14.822Z" }, - { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149, upload-time = "2024-10-18T15:21:15.642Z" }, - { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118, upload-time = "2024-10-18T15:21:17.133Z" }, - { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993, upload-time = "2024-10-18T15:21:18.064Z" }, - { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178, upload-time = "2024-10-18T15:21:18.859Z" }, - { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319, upload-time = "2024-10-18T15:21:19.671Z" }, - { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352, upload-time = "2024-10-18T15:21:20.971Z" }, - { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097, upload-time = "2024-10-18T15:21:22.646Z" }, - { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601, upload-time = "2024-10-18T15:21:23.499Z" }, - { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274, upload-time = "2024-10-18T15:21:24.577Z" }, - { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352, upload-time = "2024-10-18T15:21:25.382Z" }, - { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122, upload-time = "2024-10-18T15:21:26.199Z" }, - { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085, upload-time = "2024-10-18T15:21:27.029Z" }, - { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978, upload-time = "2024-10-18T15:21:27.846Z" }, - { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208, upload-time = "2024-10-18T15:21:28.744Z" }, - { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357, upload-time = "2024-10-18T15:21:29.545Z" }, - { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344, upload-time = "2024-10-18T15:21:30.366Z" }, - { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101, upload-time = "2024-10-18T15:21:31.207Z" }, - { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603, upload-time = "2024-10-18T15:21:32.032Z" }, - { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510, upload-time = "2024-10-18T15:21:33.625Z" }, - { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486, upload-time = "2024-10-18T15:21:34.611Z" }, - { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480, upload-time = "2024-10-18T15:21:35.398Z" }, - { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914, upload-time = "2024-10-18T15:21:36.231Z" }, - { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796, upload-time = "2024-10-18T15:21:37.073Z" }, - { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473, upload-time = "2024-10-18T15:21:37.932Z" }, - { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114, upload-time = "2024-10-18T15:21:39.799Z" }, - { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098, upload-time = "2024-10-18T15:21:40.813Z" }, - { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208, upload-time = "2024-10-18T15:21:41.814Z" }, - { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739, upload-time = "2024-10-18T15:21:42.784Z" }, +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/08/db/fefacb2136439fc8dd20e797950e749aa1f4997ed584c62cfb8ef7c2be0e/markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad", size = 11631, upload-time = "2025-09-27T18:36:18.185Z" }, + { url = "https://files.pythonhosted.org/packages/e1/2e/5898933336b61975ce9dc04decbc0a7f2fee78c30353c5efba7f2d6ff27a/markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a", size = 12058, upload-time = "2025-09-27T18:36:19.444Z" }, + { url = "https://files.pythonhosted.org/packages/1d/09/adf2df3699d87d1d8184038df46a9c80d78c0148492323f4693df54e17bb/markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50", size = 24287, upload-time = "2025-09-27T18:36:20.768Z" }, + { url = "https://files.pythonhosted.org/packages/30/ac/0273f6fcb5f42e314c6d8cd99effae6a5354604d461b8d392b5ec9530a54/markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf", size = 22940, upload-time = "2025-09-27T18:36:22.249Z" }, + { url = "https://files.pythonhosted.org/packages/19/ae/31c1be199ef767124c042c6c3e904da327a2f7f0cd63a0337e1eca2967a8/markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f", size = 21887, upload-time = "2025-09-27T18:36:23.535Z" }, + { url = "https://files.pythonhosted.org/packages/b2/76/7edcab99d5349a4532a459e1fe64f0b0467a3365056ae550d3bcf3f79e1e/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a", size = 23692, upload-time = "2025-09-27T18:36:24.823Z" }, + { url = "https://files.pythonhosted.org/packages/a4/28/6e74cdd26d7514849143d69f0bf2399f929c37dc2b31e6829fd2045b2765/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115", size = 21471, upload-time = "2025-09-27T18:36:25.95Z" }, + { url = "https://files.pythonhosted.org/packages/62/7e/a145f36a5c2945673e590850a6f8014318d5577ed7e5920a4b3448e0865d/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a", size = 22923, upload-time = "2025-09-27T18:36:27.109Z" }, + { url = "https://files.pythonhosted.org/packages/0f/62/d9c46a7f5c9adbeeeda52f5b8d802e1094e9717705a645efc71b0913a0a8/markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19", size = 14572, upload-time = "2025-09-27T18:36:28.045Z" }, + { url = "https://files.pythonhosted.org/packages/83/8a/4414c03d3f891739326e1783338e48fb49781cc915b2e0ee052aa490d586/markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01", size = 15077, upload-time = "2025-09-27T18:36:29.025Z" }, + { url = "https://files.pythonhosted.org/packages/35/73/893072b42e6862f319b5207adc9ae06070f095b358655f077f69a35601f0/markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c", size = 13876, upload-time = "2025-09-27T18:36:29.954Z" }, + { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, + { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, + { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" }, + { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" }, + { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" }, + { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" }, + { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, + { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, + { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, ] [[package]] @@ -1818,56 +1805,56 @@ wheels = [ [[package]] name = "numba" -version = "0.61.2" +version = "0.62.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "llvmlite" }, { name = "numpy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1c/a0/e21f57604304aa03ebb8e098429222722ad99176a4f979d34af1d1ee80da/numba-0.61.2.tar.gz", hash = "sha256:8750ee147940a6637b80ecf7f95062185ad8726c8c28a2295b8ec1160a196f7d", size = 2820615, upload-time = "2025-04-09T02:58:07.659Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a3/20/33dbdbfe60e5fd8e3dbfde299d106279a33d9f8308346022316781368591/numba-0.62.1.tar.gz", hash = "sha256:7b774242aa890e34c21200a1fc62e5b5757d5286267e71103257f4e2af0d5161", size = 2749817, upload-time = "2025-09-29T10:46:31.551Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3f/97/c99d1056aed767503c228f7099dc11c402906b42a4757fec2819329abb98/numba-0.61.2-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:efd3db391df53aaa5cfbee189b6c910a5b471488749fd6606c3f33fc984c2ae2", size = 2775825, upload-time = "2025-04-09T02:57:43.442Z" }, - { url = "https://files.pythonhosted.org/packages/95/9e/63c549f37136e892f006260c3e2613d09d5120672378191f2dc387ba65a2/numba-0.61.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:49c980e4171948ffebf6b9a2520ea81feed113c1f4890747ba7f59e74be84b1b", size = 2778695, upload-time = "2025-04-09T02:57:44.968Z" }, - { url = "https://files.pythonhosted.org/packages/97/c8/8740616c8436c86c1b9a62e72cb891177d2c34c2d24ddcde4c390371bf4c/numba-0.61.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3945615cd73c2c7eba2a85ccc9c1730c21cd3958bfcf5a44302abae0fb07bb60", size = 3829227, upload-time = "2025-04-09T02:57:46.63Z" }, - { url = "https://files.pythonhosted.org/packages/fc/06/66e99ae06507c31d15ff3ecd1f108f2f59e18b6e08662cd5f8a5853fbd18/numba-0.61.2-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbfdf4eca202cebade0b7d43896978e146f39398909a42941c9303f82f403a18", size = 3523422, upload-time = "2025-04-09T02:57:48.222Z" }, - { url = "https://files.pythonhosted.org/packages/0f/a4/2b309a6a9f6d4d8cfba583401c7c2f9ff887adb5d54d8e2e130274c0973f/numba-0.61.2-cp311-cp311-win_amd64.whl", hash = "sha256:76bcec9f46259cedf888041b9886e257ae101c6268261b19fda8cfbc52bec9d1", size = 2831505, upload-time = "2025-04-09T02:57:50.108Z" }, - { url = "https://files.pythonhosted.org/packages/b4/a0/c6b7b9c615cfa3b98c4c63f4316e3f6b3bbe2387740277006551784218cd/numba-0.61.2-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:34fba9406078bac7ab052efbf0d13939426c753ad72946baaa5bf9ae0ebb8dd2", size = 2776626, upload-time = "2025-04-09T02:57:51.857Z" }, - { url = "https://files.pythonhosted.org/packages/92/4a/fe4e3c2ecad72d88f5f8cd04e7f7cff49e718398a2fac02d2947480a00ca/numba-0.61.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4ddce10009bc097b080fc96876d14c051cc0c7679e99de3e0af59014dab7dfe8", size = 2779287, upload-time = "2025-04-09T02:57:53.658Z" }, - { url = "https://files.pythonhosted.org/packages/9a/2d/e518df036feab381c23a624dac47f8445ac55686ec7f11083655eb707da3/numba-0.61.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5b1bb509d01f23d70325d3a5a0e237cbc9544dd50e50588bc581ba860c213546", size = 3885928, upload-time = "2025-04-09T02:57:55.206Z" }, - { url = "https://files.pythonhosted.org/packages/10/0f/23cced68ead67b75d77cfcca3df4991d1855c897ee0ff3fe25a56ed82108/numba-0.61.2-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:48a53a3de8f8793526cbe330f2a39fe9a6638efcbf11bd63f3d2f9757ae345cd", size = 3577115, upload-time = "2025-04-09T02:57:56.818Z" }, - { url = "https://files.pythonhosted.org/packages/68/1d/ddb3e704c5a8fb90142bf9dc195c27db02a08a99f037395503bfbc1d14b3/numba-0.61.2-cp312-cp312-win_amd64.whl", hash = "sha256:97cf4f12c728cf77c9c1d7c23707e4d8fb4632b46275f8f3397de33e5877af18", size = 2831929, upload-time = "2025-04-09T02:57:58.45Z" }, - { url = "https://files.pythonhosted.org/packages/0b/f3/0fe4c1b1f2569e8a18ad90c159298d862f96c3964392a20d74fc628aee44/numba-0.61.2-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:3a10a8fc9afac40b1eac55717cece1b8b1ac0b946f5065c89e00bde646b5b154", size = 2771785, upload-time = "2025-04-09T02:57:59.96Z" }, - { url = "https://files.pythonhosted.org/packages/e9/71/91b277d712e46bd5059f8a5866862ed1116091a7cb03bd2704ba8ebe015f/numba-0.61.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7d3bcada3c9afba3bed413fba45845f2fb9cd0d2b27dd58a1be90257e293d140", size = 2773289, upload-time = "2025-04-09T02:58:01.435Z" }, - { url = "https://files.pythonhosted.org/packages/0d/e0/5ea04e7ad2c39288c0f0f9e8d47638ad70f28e275d092733b5817cf243c9/numba-0.61.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bdbca73ad81fa196bd53dc12e3aaf1564ae036e0c125f237c7644fe64a4928ab", size = 3893918, upload-time = "2025-04-09T02:58:02.933Z" }, - { url = "https://files.pythonhosted.org/packages/17/58/064f4dcb7d7e9412f16ecf80ed753f92297e39f399c905389688cf950b81/numba-0.61.2-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:5f154aaea625fb32cfbe3b80c5456d514d416fcdf79733dd69c0df3a11348e9e", size = 3584056, upload-time = "2025-04-09T02:58:04.538Z" }, - { url = "https://files.pythonhosted.org/packages/af/a4/6d3a0f2d3989e62a18749e1e9913d5fa4910bbb3e3311a035baea6caf26d/numba-0.61.2-cp313-cp313-win_amd64.whl", hash = "sha256:59321215e2e0ac5fa928a8020ab00b8e57cda8a97384963ac0dfa4d4e6aa54e7", size = 2831846, upload-time = "2025-04-09T02:58:06.125Z" }, + { url = "https://files.pythonhosted.org/packages/dd/5f/8b3491dd849474f55e33c16ef55678ace1455c490555337899c35826836c/numba-0.62.1-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:f43e24b057714e480fe44bc6031de499e7cf8150c63eb461192caa6cc8530bc8", size = 2684279, upload-time = "2025-09-29T10:43:37.213Z" }, + { url = "https://files.pythonhosted.org/packages/bf/18/71969149bfeb65a629e652b752b80167fe8a6a6f6e084f1f2060801f7f31/numba-0.62.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:57cbddc53b9ee02830b828a8428757f5c218831ccc96490a314ef569d8342b7b", size = 2687330, upload-time = "2025-09-29T10:43:59.601Z" }, + { url = "https://files.pythonhosted.org/packages/0e/7d/403be3fecae33088027bc8a95dc80a2fda1e3beff3e0e5fc4374ada3afbe/numba-0.62.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:604059730c637c7885386521bb1b0ddcbc91fd56131a6dcc54163d6f1804c872", size = 3739727, upload-time = "2025-09-29T10:42:45.922Z" }, + { url = "https://files.pythonhosted.org/packages/e0/c3/3d910d08b659a6d4c62ab3cd8cd93c4d8b7709f55afa0d79a87413027ff6/numba-0.62.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d6c540880170bee817011757dc9049dba5a29db0c09b4d2349295991fe3ee55f", size = 3445490, upload-time = "2025-09-29T10:43:12.692Z" }, + { url = "https://files.pythonhosted.org/packages/5b/82/9d425c2f20d9f0a37f7cb955945a553a00fa06a2b025856c3550227c5543/numba-0.62.1-cp311-cp311-win_amd64.whl", hash = "sha256:03de6d691d6b6e2b76660ba0f38f37b81ece8b2cc524a62f2a0cfae2bfb6f9da", size = 2745550, upload-time = "2025-09-29T10:44:20.571Z" }, + { url = "https://files.pythonhosted.org/packages/5e/fa/30fa6873e9f821c0ae755915a3ca444e6ff8d6a7b6860b669a3d33377ac7/numba-0.62.1-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:1b743b32f8fa5fff22e19c2e906db2f0a340782caf024477b97801b918cf0494", size = 2685346, upload-time = "2025-09-29T10:43:43.677Z" }, + { url = "https://files.pythonhosted.org/packages/a9/d5/504ce8dc46e0dba2790c77e6b878ee65b60fe3e7d6d0006483ef6fde5a97/numba-0.62.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:90fa21b0142bcf08ad8e32a97d25d0b84b1e921bc9423f8dda07d3652860eef6", size = 2688139, upload-time = "2025-09-29T10:44:04.894Z" }, + { url = "https://files.pythonhosted.org/packages/50/5f/6a802741176c93f2ebe97ad90751894c7b0c922b52ba99a4395e79492205/numba-0.62.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6ef84d0ac19f1bf80431347b6f4ce3c39b7ec13f48f233a48c01e2ec06ecbc59", size = 3796453, upload-time = "2025-09-29T10:42:52.771Z" }, + { url = "https://files.pythonhosted.org/packages/7e/df/efd21527d25150c4544eccc9d0b7260a5dec4b7e98b5a581990e05a133c0/numba-0.62.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9315cc5e441300e0ca07c828a627d92a6802bcbf27c5487f31ae73783c58da53", size = 3496451, upload-time = "2025-09-29T10:43:19.279Z" }, + { url = "https://files.pythonhosted.org/packages/80/44/79bfdab12a02796bf4f1841630355c82b5a69933b1d50eb15c7fa37dabe8/numba-0.62.1-cp312-cp312-win_amd64.whl", hash = "sha256:44e3aa6228039992f058f5ebfcfd372c83798e9464297bdad8cc79febcf7891e", size = 2745552, upload-time = "2025-09-29T10:44:26.399Z" }, + { url = "https://files.pythonhosted.org/packages/22/76/501ea2c07c089ef1386868f33dff2978f43f51b854e34397b20fc55e0a58/numba-0.62.1-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:b72489ba8411cc9fdcaa2458d8f7677751e94f0109eeb53e5becfdc818c64afb", size = 2685766, upload-time = "2025-09-29T10:43:49.161Z" }, + { url = "https://files.pythonhosted.org/packages/80/68/444986ed95350c0611d5c7b46828411c222ce41a0c76707c36425d27ce29/numba-0.62.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:44a1412095534a26fb5da2717bc755b57da5f3053965128fe3dc286652cc6a92", size = 2688741, upload-time = "2025-09-29T10:44:10.07Z" }, + { url = "https://files.pythonhosted.org/packages/78/7e/bf2e3634993d57f95305c7cee4c9c6cb3c9c78404ee7b49569a0dfecfe33/numba-0.62.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8c9460b9e936c5bd2f0570e20a0a5909ee6e8b694fd958b210e3bde3a6dba2d7", size = 3804576, upload-time = "2025-09-29T10:42:59.53Z" }, + { url = "https://files.pythonhosted.org/packages/e8/b6/8a1723fff71f63bbb1354bdc60a1513a068acc0f5322f58da6f022d20247/numba-0.62.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:728f91a874192df22d74e3fd42c12900b7ce7190b1aad3574c6c61b08313e4c5", size = 3503367, upload-time = "2025-09-29T10:43:26.326Z" }, + { url = "https://files.pythonhosted.org/packages/9c/ec/9d414e7a80d6d1dc4af0e07c6bfe293ce0b04ea4d0ed6c45dad9bd6e72eb/numba-0.62.1-cp313-cp313-win_amd64.whl", hash = "sha256:bbf3f88b461514287df66bc8d0307e949b09f2b6f67da92265094e8fa1282dd8", size = 2745529, upload-time = "2025-09-29T10:44:31.738Z" }, ] [[package]] name = "numcodecs" -version = "0.16.2" +version = "0.16.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a1/1d/837d946aab385abe1e472ec08a6816d84b00f4ceeae5445eb8f25c5c6ca9/numcodecs-0.16.2.tar.gz", hash = "sha256:9922dae0c3b01b5bed3b4bae239f4787e891daa3262c27971298669d029d10e9", size = 6271668, upload-time = "2025-08-13T16:09:26.125Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/19/38b3fbb2335e31fdd253e1de0531b32e8245b86a7b9d46c474fa6d2cb5c5/numcodecs-0.16.2-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:4c1f1357896cfc5451157fd90a2858aa0f6a66409f91f3016d257b76c4c244c1", size = 1629357, upload-time = "2025-08-13T16:09:00.425Z" }, - { url = "https://files.pythonhosted.org/packages/3d/f8/ba257b7627477f5650aa8274e7a6f9a72c4d51c1e7ac968b14b65d872c76/numcodecs-0.16.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d88aa4f82bb8fe3fa2e9c19fd44b6c268acec6fc7bcff59c92e169830d09531a", size = 1158894, upload-time = "2025-08-13T16:09:02.285Z" }, - { url = "https://files.pythonhosted.org/packages/e3/31/0c90266a9ba048223656d552c5b40ea22d788be77797e8a0db9d698a3847/numcodecs-0.16.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:276f657ec4ffef9e2cc344b732b8906fe8612c3b9484504830ccdc7a2dd0715a", size = 8285212, upload-time = "2025-08-13T16:09:03.716Z" }, - { url = "https://files.pythonhosted.org/packages/01/24/7889b678c0b7e3f605e1ec2fe1ddee0f48920098fecb0cadd5bd66483044/numcodecs-0.16.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1b7d8174e14c66191e0e1a4a44dd264bd776fb96b1ce3adc0216154f34b755c", size = 8811508, upload-time = "2025-08-13T16:09:05.68Z" }, - { url = "https://files.pythonhosted.org/packages/87/26/23b474b188a8e005bbd5e516e3415ec9f2b59fbf1f36636e5cfc14f59c54/numcodecs-0.16.2-cp311-cp311-win_amd64.whl", hash = "sha256:559163a7d97ec8aef1654e47c6e97f88dcc4c38a975338bf1bfb214d3c8d70f9", size = 804099, upload-time = "2025-08-13T16:09:07.589Z" }, - { url = "https://files.pythonhosted.org/packages/03/c3/5470273d6d5c986521140ccec6476664ea4e03c0cfc51b370fb03368bb41/numcodecs-0.16.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:30f04c2b7bb802133866e7fb554d47943864f977dfe8a95c814eb801c797df3c", size = 1668488, upload-time = "2025-08-13T16:09:08.942Z" }, - { url = "https://files.pythonhosted.org/packages/db/bf/cc1aaea87371097d6b5236ec44f8eb96387b52204b4e671fac716e5de325/numcodecs-0.16.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8ee0b2776cf47b7702ba0ccc0b6afaad28afbf8d5bb7b9a5274b5f08ecc651b2", size = 1155083, upload-time = "2025-08-13T16:09:10.641Z" }, - { url = "https://files.pythonhosted.org/packages/6b/c1/ba5ab0cf4c4d737635d20d8b72a61c26f8f99c0529606dfbfa3e5d3a4221/numcodecs-0.16.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c8e94f0e90aaf4d01b2e26476d3b081c2cf8c17036af45e04e735de9c0cf64f", size = 8260568, upload-time = "2025-08-13T16:09:12.063Z" }, - { url = "https://files.pythonhosted.org/packages/3b/64/7177bf632520705893683fa4ca202ed540450bf971c0453ad1351baa2007/numcodecs-0.16.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b565b16366749011e290343617571db861b2b2e58b038697afde6d02f537c91", size = 8792262, upload-time = "2025-08-13T16:09:14.058Z" }, - { url = "https://files.pythonhosted.org/packages/10/90/df01799f4c1bb8618b842582d10d362829e980c4d5eb9701c1aeadf5c4e3/numcodecs-0.16.2-cp312-cp312-win_amd64.whl", hash = "sha256:e4cfdde4e99bf47580f4eb3a876630c73ba14e4a1380fec5959ac727e22ce0d2", size = 803444, upload-time = "2025-08-13T16:09:16.09Z" }, - { url = "https://files.pythonhosted.org/packages/b6/e3/f61c422259a4b6c8c2496d284f85ed17f8686b3a53feb797d3bd66ef499c/numcodecs-0.16.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0f965ccb2f6d215ffd2e3239ec02e33139d7ce311ff49704d340704b81dda653", size = 1664476, upload-time = "2025-08-13T16:09:17.327Z" }, - { url = "https://files.pythonhosted.org/packages/b9/a7/fa4d66b86e277643d135af263efc0dd1f98cf1228d3b4554b843c0c1a09b/numcodecs-0.16.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b4bc110b73d59de7f46310c680f075f9007ead915174c895368274c646c9ea74", size = 1148718, upload-time = "2025-08-13T16:09:19.075Z" }, - { url = "https://files.pythonhosted.org/packages/17/43/9656a6b0ed7250ca3a5c126a6077a29398c3dca9176224dba4634847a4a4/numcodecs-0.16.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51615cf2811343a8a3fa42953cb4120ac7187875a161260444f53ada5710063e", size = 8205330, upload-time = "2025-08-13T16:09:20.904Z" }, - { url = "https://files.pythonhosted.org/packages/55/7f/0ab8db32ef9b51c60f7b759c2b155e1edcb08febb508c22a9d04b19ec735/numcodecs-0.16.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a18ced1ecbdd0e9ee716820dbb3a094c896eed8005273bbcab9980bdac270ae", size = 8750769, upload-time = "2025-08-13T16:09:22.516Z" }, - { url = "https://files.pythonhosted.org/packages/f0/0c/25f96c7969bdbfcc1427dc82eba92f2ef4df84c63369c95ab99af6404c23/numcodecs-0.16.2-cp313-cp313-win_amd64.whl", hash = "sha256:f640ed8406e1eb5806787a3e5be223d455b75c99eb2088a290947ed6dbd77e8e", size = 800281, upload-time = "2025-08-13T16:09:24.691Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/f6/48/6188e359b90a9d8a1850f2bc888c023e66f4a8b2b496820babbea414f008/numcodecs-0.16.3.tar.gz", hash = "sha256:53d705865faaf0a7927c973af3777532001c8fbb653de119c1e844608614d799", size = 6275704, upload-time = "2025-09-18T18:54:57.221Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d4/cc/917a85972537498f2bbd7914047efc98babc8667587ceb9dcb228378978a/numcodecs-0.16.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:95c9f2a49bef10cf91ad614a761cba9bfe96656b60c12540e1080de5d909b4ca", size = 1642356, upload-time = "2025-09-18T18:54:36.402Z" }, + { url = "https://files.pythonhosted.org/packages/3b/6a/64c25a089e8537441fe67c09ecb7f3f7fb5d98cd04faf01f605d43aca41c/numcodecs-0.16.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2afe73d5ebaf9ca0cd5c83aad945da80d29a33d860a80d43a7248491d8813ff", size = 1169186, upload-time = "2025-09-18T18:54:37.838Z" }, + { url = "https://files.pythonhosted.org/packages/d8/a0/0de627baeb43e2045a3d4b3de99bf8b69af329a33df1ed4cda468d70c1fb/numcodecs-0.16.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:913f08194d82dcb37594e6705e6d4ae6ccd4b6571500b832fb3e4a155de1dfe8", size = 8341668, upload-time = "2025-09-18T18:54:39.444Z" }, + { url = "https://files.pythonhosted.org/packages/b6/0f/49d1f74a216149240c4b9403218111f11670bd11af0919fda357bb056bf2/numcodecs-0.16.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85a7f1cae9eb18b85709af46570bf9c60056e7155c4c8f610e8080c68124d0e5", size = 8866611, upload-time = "2025-09-18T18:54:41.168Z" }, + { url = "https://files.pythonhosted.org/packages/aa/51/03aece765108fe247717105b5131856546e5428f22a56a14ffdebd017424/numcodecs-0.16.3-cp311-cp311-win_amd64.whl", hash = "sha256:f7bb7f2c46eb7ec8a1c5f8d8fe1a72c222256dd6d6df5af9eaac7a6b905f3575", size = 806787, upload-time = "2025-09-18T18:54:42.78Z" }, + { url = "https://files.pythonhosted.org/packages/0d/78/e4b34803a3aa1d0769919695de4b133266c18c80c474d32ebc462fa1a9bd/numcodecs-0.16.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c77454d92941a335d148b0b822f5d4783103f392774d5d76283bbf7f21b49529", size = 1681108, upload-time = "2025-09-18T18:54:43.856Z" }, + { url = "https://files.pythonhosted.org/packages/25/cf/ca36f463b03a4097767d2a1c1b72f31810e8c6384e9449dd9b925203783c/numcodecs-0.16.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:270e7a33ee96bdf5c957acf25a2487002a233811a125a155c400c2f036b69c73", size = 1165589, upload-time = "2025-09-18T18:54:44.954Z" }, + { url = "https://files.pythonhosted.org/packages/ed/ae/670260c3c4b5ed34a0674561355f3d4ce7fcbdf09a667e5bc841526d271c/numcodecs-0.16.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12f43fa4a347d1dba775c4506a1c9b15b90144c258433b81f79f1c1b1a990db5", size = 8316365, upload-time = "2025-09-18T18:54:46.073Z" }, + { url = "https://files.pythonhosted.org/packages/bb/fa/94e022419c751a60ff0f53642ebae5ef81ed3cc3640f958588e3ad3dc18d/numcodecs-0.16.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44869ef564a50aa545215c6a0d42ba5bbc34e9715523fb2336ada3d1fb2b331d", size = 8846228, upload-time = "2025-09-18T18:54:47.858Z" }, + { url = "https://files.pythonhosted.org/packages/71/60/f23733589f3e059bf8589508acd23ffeec230bdf179f138a54f5ab16e0a6/numcodecs-0.16.3-cp312-cp312-win_amd64.whl", hash = "sha256:9aae6996172ba10c5f5111b2998709071b5aeba6b58b1ee0b26b61ed6aa7f2f4", size = 806260, upload-time = "2025-09-18T18:54:49.41Z" }, + { url = "https://files.pythonhosted.org/packages/3c/d5/d3536d06ac1e5fb848a3186958204082b68b106364c9a3669652dd786731/numcodecs-0.16.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:947406b01c20f2ce7ce2e631e7f21b782e8a9d4b57b374a41c9e7b1341a8f3a2", size = 1677129, upload-time = "2025-09-18T18:54:50.5Z" }, + { url = "https://files.pythonhosted.org/packages/e1/fd/b0513a3428dc2b38ec85eea771703ae69c49f09b9650d6c44c9105c80073/numcodecs-0.16.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7cf50e351398a34b45817974c411527629e88937b7683695e276afd65da6ed6f", size = 1159058, upload-time = "2025-09-18T18:54:51.675Z" }, + { url = "https://files.pythonhosted.org/packages/98/05/b7c127283cfb154a97abb284363825401b69302d71a28608af66f73257cc/numcodecs-0.16.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7938502fcc060ed9543814f38ca67048b33d7bd2667756e36e6b1060455b17e", size = 8260987, upload-time = "2025-09-18T18:54:52.883Z" }, + { url = "https://files.pythonhosted.org/packages/ff/46/320d960aff884bc63abaaf846ffa3de4803e83e8070b6f84c5688464839c/numcodecs-0.16.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:010d628c95be1214536fb22c0df4ced58da954b404b1fcb25ddebf64e4a3f7f3", size = 8805295, upload-time = "2025-09-18T18:54:54.698Z" }, + { url = "https://files.pythonhosted.org/packages/31/ae/acc2e0f1f49ba32afa2174578f170673139248ef86f77e334f2619133867/numcodecs-0.16.3-cp313-cp313-win_amd64.whl", hash = "sha256:e83115e3c32de798c7b7164503e06aae9f9746c1cef564d029616eb44bd6cd90", size = 803204, upload-time = "2025-09-18T18:54:56.192Z" }, ] [package.optional-dependencies] @@ -1877,62 +1864,73 @@ crc32c = [ [[package]] name = "numpy" -version = "2.2.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload-time = "2025-05-17T22:38:04.611Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/da/a8/4f83e2aa666a9fbf56d6118faaaf5f1974d456b1823fda0a176eff722839/numpy-2.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f9f1adb22318e121c5c69a09142811a201ef17ab257a1e66ca3025065b7f53ae", size = 21176963, upload-time = "2025-05-17T21:31:19.36Z" }, - { url = "https://files.pythonhosted.org/packages/b3/2b/64e1affc7972decb74c9e29e5649fac940514910960ba25cd9af4488b66c/numpy-2.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c820a93b0255bc360f53eca31a0e676fd1101f673dda8da93454a12e23fc5f7a", size = 14406743, upload-time = "2025-05-17T21:31:41.087Z" }, - { url = "https://files.pythonhosted.org/packages/4a/9f/0121e375000b5e50ffdd8b25bf78d8e1a5aa4cca3f185d41265198c7b834/numpy-2.2.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3d70692235e759f260c3d837193090014aebdf026dfd167834bcba43e30c2a42", size = 5352616, upload-time = "2025-05-17T21:31:50.072Z" }, - { url = "https://files.pythonhosted.org/packages/31/0d/b48c405c91693635fbe2dcd7bc84a33a602add5f63286e024d3b6741411c/numpy-2.2.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:481b49095335f8eed42e39e8041327c05b0f6f4780488f61286ed3c01368d491", size = 6889579, upload-time = "2025-05-17T21:32:01.712Z" }, - { url = "https://files.pythonhosted.org/packages/52/b8/7f0554d49b565d0171eab6e99001846882000883998e7b7d9f0d98b1f934/numpy-2.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b64d8d4d17135e00c8e346e0a738deb17e754230d7e0810ac5012750bbd85a5a", size = 14312005, upload-time = "2025-05-17T21:32:23.332Z" }, - { url = "https://files.pythonhosted.org/packages/b3/dd/2238b898e51bd6d389b7389ffb20d7f4c10066d80351187ec8e303a5a475/numpy-2.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba10f8411898fc418a521833e014a77d3ca01c15b0c6cdcce6a0d2897e6dbbdf", size = 16821570, upload-time = "2025-05-17T21:32:47.991Z" }, - { url = "https://files.pythonhosted.org/packages/83/6c/44d0325722cf644f191042bf47eedad61c1e6df2432ed65cbe28509d404e/numpy-2.2.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bd48227a919f1bafbdda0583705e547892342c26fb127219d60a5c36882609d1", size = 15818548, upload-time = "2025-05-17T21:33:11.728Z" }, - { url = "https://files.pythonhosted.org/packages/ae/9d/81e8216030ce66be25279098789b665d49ff19eef08bfa8cb96d4957f422/numpy-2.2.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9551a499bf125c1d4f9e250377c1ee2eddd02e01eac6644c080162c0c51778ab", size = 18620521, upload-time = "2025-05-17T21:33:39.139Z" }, - { url = "https://files.pythonhosted.org/packages/6a/fd/e19617b9530b031db51b0926eed5345ce8ddc669bb3bc0044b23e275ebe8/numpy-2.2.6-cp311-cp311-win32.whl", hash = "sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47", size = 6525866, upload-time = "2025-05-17T21:33:50.273Z" }, - { url = "https://files.pythonhosted.org/packages/31/0a/f354fb7176b81747d870f7991dc763e157a934c717b67b58456bc63da3df/numpy-2.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303", size = 12907455, upload-time = "2025-05-17T21:34:09.135Z" }, - { url = "https://files.pythonhosted.org/packages/82/5d/c00588b6cf18e1da539b45d3598d3557084990dcc4331960c15ee776ee41/numpy-2.2.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41c5a21f4a04fa86436124d388f6ed60a9343a6f767fced1a8a71c3fbca038ff", size = 20875348, upload-time = "2025-05-17T21:34:39.648Z" }, - { url = "https://files.pythonhosted.org/packages/66/ee/560deadcdde6c2f90200450d5938f63a34b37e27ebff162810f716f6a230/numpy-2.2.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de749064336d37e340f640b05f24e9e3dd678c57318c7289d222a8a2f543e90c", size = 14119362, upload-time = "2025-05-17T21:35:01.241Z" }, - { url = "https://files.pythonhosted.org/packages/3c/65/4baa99f1c53b30adf0acd9a5519078871ddde8d2339dc5a7fde80d9d87da/numpy-2.2.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:894b3a42502226a1cac872f840030665f33326fc3dac8e57c607905773cdcde3", size = 5084103, upload-time = "2025-05-17T21:35:10.622Z" }, - { url = "https://files.pythonhosted.org/packages/cc/89/e5a34c071a0570cc40c9a54eb472d113eea6d002e9ae12bb3a8407fb912e/numpy-2.2.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:71594f7c51a18e728451bb50cc60a3ce4e6538822731b2933209a1f3614e9282", size = 6625382, upload-time = "2025-05-17T21:35:21.414Z" }, - { url = "https://files.pythonhosted.org/packages/f8/35/8c80729f1ff76b3921d5c9487c7ac3de9b2a103b1cd05e905b3090513510/numpy-2.2.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2618db89be1b4e05f7a1a847a9c1c0abd63e63a1607d892dd54668dd92faf87", size = 14018462, upload-time = "2025-05-17T21:35:42.174Z" }, - { url = "https://files.pythonhosted.org/packages/8c/3d/1e1db36cfd41f895d266b103df00ca5b3cbe965184df824dec5c08c6b803/numpy-2.2.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd83c01228a688733f1ded5201c678f0c53ecc1006ffbc404db9f7a899ac6249", size = 16527618, upload-time = "2025-05-17T21:36:06.711Z" }, - { url = "https://files.pythonhosted.org/packages/61/c6/03ed30992602c85aa3cd95b9070a514f8b3c33e31124694438d88809ae36/numpy-2.2.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:37c0ca431f82cd5fa716eca9506aefcabc247fb27ba69c5062a6d3ade8cf8f49", size = 15505511, upload-time = "2025-05-17T21:36:29.965Z" }, - { url = "https://files.pythonhosted.org/packages/b7/25/5761d832a81df431e260719ec45de696414266613c9ee268394dd5ad8236/numpy-2.2.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fe27749d33bb772c80dcd84ae7e8df2adc920ae8297400dabec45f0dedb3f6de", size = 18313783, upload-time = "2025-05-17T21:36:56.883Z" }, - { url = "https://files.pythonhosted.org/packages/57/0a/72d5a3527c5ebffcd47bde9162c39fae1f90138c961e5296491ce778e682/numpy-2.2.6-cp312-cp312-win32.whl", hash = "sha256:4eeaae00d789f66c7a25ac5f34b71a7035bb474e679f410e5e1a94deb24cf2d4", size = 6246506, upload-time = "2025-05-17T21:37:07.368Z" }, - { url = "https://files.pythonhosted.org/packages/36/fa/8c9210162ca1b88529ab76b41ba02d433fd54fecaf6feb70ef9f124683f1/numpy-2.2.6-cp312-cp312-win_amd64.whl", hash = "sha256:c1f9540be57940698ed329904db803cf7a402f3fc200bfe599334c9bd84a40b2", size = 12614190, upload-time = "2025-05-17T21:37:26.213Z" }, - { url = "https://files.pythonhosted.org/packages/f9/5c/6657823f4f594f72b5471f1db1ab12e26e890bb2e41897522d134d2a3e81/numpy-2.2.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0811bb762109d9708cca4d0b13c4f67146e3c3b7cf8d34018c722adb2d957c84", size = 20867828, upload-time = "2025-05-17T21:37:56.699Z" }, - { url = "https://files.pythonhosted.org/packages/dc/9e/14520dc3dadf3c803473bd07e9b2bd1b69bc583cb2497b47000fed2fa92f/numpy-2.2.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:287cc3162b6f01463ccd86be154f284d0893d2b3ed7292439ea97eafa8170e0b", size = 14143006, upload-time = "2025-05-17T21:38:18.291Z" }, - { url = "https://files.pythonhosted.org/packages/4f/06/7e96c57d90bebdce9918412087fc22ca9851cceaf5567a45c1f404480e9e/numpy-2.2.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f1372f041402e37e5e633e586f62aa53de2eac8d98cbfb822806ce4bbefcb74d", size = 5076765, upload-time = "2025-05-17T21:38:27.319Z" }, - { url = "https://files.pythonhosted.org/packages/73/ed/63d920c23b4289fdac96ddbdd6132e9427790977d5457cd132f18e76eae0/numpy-2.2.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:55a4d33fa519660d69614a9fad433be87e5252f4b03850642f88993f7b2ca566", size = 6617736, upload-time = "2025-05-17T21:38:38.141Z" }, - { url = "https://files.pythonhosted.org/packages/85/c5/e19c8f99d83fd377ec8c7e0cf627a8049746da54afc24ef0a0cb73d5dfb5/numpy-2.2.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f92729c95468a2f4f15e9bb94c432a9229d0d50de67304399627a943201baa2f", size = 14010719, upload-time = "2025-05-17T21:38:58.433Z" }, - { url = "https://files.pythonhosted.org/packages/19/49/4df9123aafa7b539317bf6d342cb6d227e49f7a35b99c287a6109b13dd93/numpy-2.2.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f", size = 16526072, upload-time = "2025-05-17T21:39:22.638Z" }, - { url = "https://files.pythonhosted.org/packages/b2/6c/04b5f47f4f32f7c2b0e7260442a8cbcf8168b0e1a41ff1495da42f42a14f/numpy-2.2.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e3143e4451880bed956e706a3220b4e5cf6172ef05fcc397f6f36a550b1dd868", size = 15503213, upload-time = "2025-05-17T21:39:45.865Z" }, - { url = "https://files.pythonhosted.org/packages/17/0a/5cd92e352c1307640d5b6fec1b2ffb06cd0dabe7d7b8227f97933d378422/numpy-2.2.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4f13750ce79751586ae2eb824ba7e1e8dba64784086c98cdbbcc6a42112ce0d", size = 18316632, upload-time = "2025-05-17T21:40:13.331Z" }, - { url = "https://files.pythonhosted.org/packages/f0/3b/5cba2b1d88760ef86596ad0f3d484b1cbff7c115ae2429678465057c5155/numpy-2.2.6-cp313-cp313-win32.whl", hash = "sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd", size = 6244532, upload-time = "2025-05-17T21:43:46.099Z" }, - { url = "https://files.pythonhosted.org/packages/cb/3b/d58c12eafcb298d4e6d0d40216866ab15f59e55d148a5658bb3132311fcf/numpy-2.2.6-cp313-cp313-win_amd64.whl", hash = "sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c", size = 12610885, upload-time = "2025-05-17T21:44:05.145Z" }, - { url = "https://files.pythonhosted.org/packages/6b/9e/4bf918b818e516322db999ac25d00c75788ddfd2d2ade4fa66f1f38097e1/numpy-2.2.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0bca768cd85ae743b2affdc762d617eddf3bcf8724435498a1e80132d04879e6", size = 20963467, upload-time = "2025-05-17T21:40:44Z" }, - { url = "https://files.pythonhosted.org/packages/61/66/d2de6b291507517ff2e438e13ff7b1e2cdbdb7cb40b3ed475377aece69f9/numpy-2.2.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fc0c5673685c508a142ca65209b4e79ed6740a4ed6b2267dbba90f34b0b3cfda", size = 14225144, upload-time = "2025-05-17T21:41:05.695Z" }, - { url = "https://files.pythonhosted.org/packages/e4/25/480387655407ead912e28ba3a820bc69af9adf13bcbe40b299d454ec011f/numpy-2.2.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:5bd4fc3ac8926b3819797a7c0e2631eb889b4118a9898c84f585a54d475b7e40", size = 5200217, upload-time = "2025-05-17T21:41:15.903Z" }, - { url = "https://files.pythonhosted.org/packages/aa/4a/6e313b5108f53dcbf3aca0c0f3e9c92f4c10ce57a0a721851f9785872895/numpy-2.2.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8", size = 6712014, upload-time = "2025-05-17T21:41:27.321Z" }, - { url = "https://files.pythonhosted.org/packages/b7/30/172c2d5c4be71fdf476e9de553443cf8e25feddbe185e0bd88b096915bcc/numpy-2.2.6-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1dda9c7e08dc141e0247a5b8f49cf05984955246a327d4c48bda16821947b2f", size = 14077935, upload-time = "2025-05-17T21:41:49.738Z" }, - { url = "https://files.pythonhosted.org/packages/12/fb/9e743f8d4e4d3c710902cf87af3512082ae3d43b945d5d16563f26ec251d/numpy-2.2.6-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f447e6acb680fd307f40d3da4852208af94afdfab89cf850986c3ca00562f4fa", size = 16600122, upload-time = "2025-05-17T21:42:14.046Z" }, - { url = "https://files.pythonhosted.org/packages/12/75/ee20da0e58d3a66f204f38916757e01e33a9737d0b22373b3eb5a27358f9/numpy-2.2.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:389d771b1623ec92636b0786bc4ae56abafad4a4c513d36a55dce14bd9ce8571", size = 15586143, upload-time = "2025-05-17T21:42:37.464Z" }, - { url = "https://files.pythonhosted.org/packages/76/95/bef5b37f29fc5e739947e9ce5179ad402875633308504a52d188302319c8/numpy-2.2.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8e9ace4a37db23421249ed236fdcdd457d671e25146786dfc96835cd951aa7c1", size = 18385260, upload-time = "2025-05-17T21:43:05.189Z" }, - { url = "https://files.pythonhosted.org/packages/09/04/f2f83279d287407cf36a7a8053a5abe7be3622a4363337338f2585e4afda/numpy-2.2.6-cp313-cp313t-win32.whl", hash = "sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff", size = 6377225, upload-time = "2025-05-17T21:43:16.254Z" }, - { url = "https://files.pythonhosted.org/packages/67/0e/35082d13c09c02c011cf21570543d202ad929d961c02a147493cb0c2bdf5/numpy-2.2.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06", size = 12771374, upload-time = "2025-05-17T21:43:35.479Z" }, +version = "2.3.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/19/95b3d357407220ed24c139018d2518fab0a61a948e68286a25f1a4d049ff/numpy-2.3.3.tar.gz", hash = "sha256:ddc7c39727ba62b80dfdbedf400d1c10ddfa8eefbd7ec8dcb118be8b56d31029", size = 20576648, upload-time = "2025-09-09T16:54:12.543Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7a/45/e80d203ef6b267aa29b22714fb558930b27960a0c5ce3c19c999232bb3eb/numpy-2.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0ffc4f5caba7dfcbe944ed674b7eef683c7e94874046454bb79ed7ee0236f59d", size = 21259253, upload-time = "2025-09-09T15:56:02.094Z" }, + { url = "https://files.pythonhosted.org/packages/52/18/cf2c648fccf339e59302e00e5f2bc87725a3ce1992f30f3f78c9044d7c43/numpy-2.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e7e946c7170858a0295f79a60214424caac2ffdb0063d4d79cb681f9aa0aa569", size = 14450980, upload-time = "2025-09-09T15:56:05.926Z" }, + { url = "https://files.pythonhosted.org/packages/93/fb/9af1082bec870188c42a1c239839915b74a5099c392389ff04215dcee812/numpy-2.3.3-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:cd4260f64bc794c3390a63bf0728220dd1a68170c169088a1e0dfa2fde1be12f", size = 5379709, upload-time = "2025-09-09T15:56:07.95Z" }, + { url = "https://files.pythonhosted.org/packages/75/0f/bfd7abca52bcbf9a4a65abc83fe18ef01ccdeb37bfb28bbd6ad613447c79/numpy-2.3.3-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:f0ddb4b96a87b6728df9362135e764eac3cfa674499943ebc44ce96c478ab125", size = 6913923, upload-time = "2025-09-09T15:56:09.443Z" }, + { url = "https://files.pythonhosted.org/packages/79/55/d69adad255e87ab7afda1caf93ca997859092afeb697703e2f010f7c2e55/numpy-2.3.3-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:afd07d377f478344ec6ca2b8d4ca08ae8bd44706763d1efb56397de606393f48", size = 14589591, upload-time = "2025-09-09T15:56:11.234Z" }, + { url = "https://files.pythonhosted.org/packages/10/a2/010b0e27ddeacab7839957d7a8f00e91206e0c2c47abbb5f35a2630e5387/numpy-2.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bc92a5dedcc53857249ca51ef29f5e5f2f8c513e22cfb90faeb20343b8c6f7a6", size = 16938714, upload-time = "2025-09-09T15:56:14.637Z" }, + { url = "https://files.pythonhosted.org/packages/1c/6b/12ce8ede632c7126eb2762b9e15e18e204b81725b81f35176eac14dc5b82/numpy-2.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7af05ed4dc19f308e1d9fc759f36f21921eb7bbfc82843eeec6b2a2863a0aefa", size = 16370592, upload-time = "2025-09-09T15:56:17.285Z" }, + { url = "https://files.pythonhosted.org/packages/b4/35/aba8568b2593067bb6a8fe4c52babb23b4c3b9c80e1b49dff03a09925e4a/numpy-2.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:433bf137e338677cebdd5beac0199ac84712ad9d630b74eceeb759eaa45ddf30", size = 18884474, upload-time = "2025-09-09T15:56:20.943Z" }, + { url = "https://files.pythonhosted.org/packages/45/fa/7f43ba10c77575e8be7b0138d107e4f44ca4a1ef322cd16980ea3e8b8222/numpy-2.3.3-cp311-cp311-win32.whl", hash = "sha256:eb63d443d7b4ffd1e873f8155260d7f58e7e4b095961b01c91062935c2491e57", size = 6599794, upload-time = "2025-09-09T15:56:23.258Z" }, + { url = "https://files.pythonhosted.org/packages/0a/a2/a4f78cb2241fe5664a22a10332f2be886dcdea8784c9f6a01c272da9b426/numpy-2.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:ec9d249840f6a565f58d8f913bccac2444235025bbb13e9a4681783572ee3caa", size = 13088104, upload-time = "2025-09-09T15:56:25.476Z" }, + { url = "https://files.pythonhosted.org/packages/79/64/e424e975adbd38282ebcd4891661965b78783de893b381cbc4832fb9beb2/numpy-2.3.3-cp311-cp311-win_arm64.whl", hash = "sha256:74c2a948d02f88c11a3c075d9733f1ae67d97c6bdb97f2bb542f980458b257e7", size = 10460772, upload-time = "2025-09-09T15:56:27.679Z" }, + { url = "https://files.pythonhosted.org/packages/51/5d/bb7fc075b762c96329147799e1bcc9176ab07ca6375ea976c475482ad5b3/numpy-2.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cfdd09f9c84a1a934cde1eec2267f0a43a7cd44b2cca4ff95b7c0d14d144b0bf", size = 20957014, upload-time = "2025-09-09T15:56:29.966Z" }, + { url = "https://files.pythonhosted.org/packages/6b/0e/c6211bb92af26517acd52125a237a92afe9c3124c6a68d3b9f81b62a0568/numpy-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cb32e3cf0f762aee47ad1ddc6672988f7f27045b0783c887190545baba73aa25", size = 14185220, upload-time = "2025-09-09T15:56:32.175Z" }, + { url = "https://files.pythonhosted.org/packages/22/f2/07bb754eb2ede9073f4054f7c0286b0d9d2e23982e090a80d478b26d35ca/numpy-2.3.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:396b254daeb0a57b1fe0ecb5e3cff6fa79a380fa97c8f7781a6d08cd429418fe", size = 5113918, upload-time = "2025-09-09T15:56:34.175Z" }, + { url = "https://files.pythonhosted.org/packages/81/0a/afa51697e9fb74642f231ea36aca80fa17c8fb89f7a82abd5174023c3960/numpy-2.3.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:067e3d7159a5d8f8a0b46ee11148fc35ca9b21f61e3c49fbd0a027450e65a33b", size = 6647922, upload-time = "2025-09-09T15:56:36.149Z" }, + { url = "https://files.pythonhosted.org/packages/5d/f5/122d9cdb3f51c520d150fef6e87df9279e33d19a9611a87c0d2cf78a89f4/numpy-2.3.3-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c02d0629d25d426585fb2e45a66154081b9fa677bc92a881ff1d216bc9919a8", size = 14281991, upload-time = "2025-09-09T15:56:40.548Z" }, + { url = "https://files.pythonhosted.org/packages/51/64/7de3c91e821a2debf77c92962ea3fe6ac2bc45d0778c1cbe15d4fce2fd94/numpy-2.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d9192da52b9745f7f0766531dcfa978b7763916f158bb63bdb8a1eca0068ab20", size = 16641643, upload-time = "2025-09-09T15:56:43.343Z" }, + { url = "https://files.pythonhosted.org/packages/30/e4/961a5fa681502cd0d68907818b69f67542695b74e3ceaa513918103b7e80/numpy-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:cd7de500a5b66319db419dc3c345244404a164beae0d0937283b907d8152e6ea", size = 16056787, upload-time = "2025-09-09T15:56:46.141Z" }, + { url = "https://files.pythonhosted.org/packages/99/26/92c912b966e47fbbdf2ad556cb17e3a3088e2e1292b9833be1dfa5361a1a/numpy-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:93d4962d8f82af58f0b2eb85daaf1b3ca23fe0a85d0be8f1f2b7bb46034e56d7", size = 18579598, upload-time = "2025-09-09T15:56:49.844Z" }, + { url = "https://files.pythonhosted.org/packages/17/b6/fc8f82cb3520768718834f310c37d96380d9dc61bfdaf05fe5c0b7653e01/numpy-2.3.3-cp312-cp312-win32.whl", hash = "sha256:5534ed6b92f9b7dca6c0a19d6df12d41c68b991cef051d108f6dbff3babc4ebf", size = 6320800, upload-time = "2025-09-09T15:56:52.499Z" }, + { url = "https://files.pythonhosted.org/packages/32/ee/de999f2625b80d043d6d2d628c07d0d5555a677a3cf78fdf868d409b8766/numpy-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:497d7cad08e7092dba36e3d296fe4c97708c93daf26643a1ae4b03f6294d30eb", size = 12786615, upload-time = "2025-09-09T15:56:54.422Z" }, + { url = "https://files.pythonhosted.org/packages/49/6e/b479032f8a43559c383acb20816644f5f91c88f633d9271ee84f3b3a996c/numpy-2.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:ca0309a18d4dfea6fc6262a66d06c26cfe4640c3926ceec90e57791a82b6eee5", size = 10195936, upload-time = "2025-09-09T15:56:56.541Z" }, + { url = "https://files.pythonhosted.org/packages/7d/b9/984c2b1ee61a8b803bf63582b4ac4242cf76e2dbd663efeafcb620cc0ccb/numpy-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f5415fb78995644253370985342cd03572ef8620b934da27d77377a2285955bf", size = 20949588, upload-time = "2025-09-09T15:56:59.087Z" }, + { url = "https://files.pythonhosted.org/packages/a6/e4/07970e3bed0b1384d22af1e9912527ecbeb47d3b26e9b6a3bced068b3bea/numpy-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d00de139a3324e26ed5b95870ce63be7ec7352171bc69a4cf1f157a48e3eb6b7", size = 14177802, upload-time = "2025-09-09T15:57:01.73Z" }, + { url = "https://files.pythonhosted.org/packages/35/c7/477a83887f9de61f1203bad89cf208b7c19cc9fef0cebef65d5a1a0619f2/numpy-2.3.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:9dc13c6a5829610cc07422bc74d3ac083bd8323f14e2827d992f9e52e22cd6a6", size = 5106537, upload-time = "2025-09-09T15:57:03.765Z" }, + { url = "https://files.pythonhosted.org/packages/52/47/93b953bd5866a6f6986344d045a207d3f1cfbad99db29f534ea9cee5108c/numpy-2.3.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:d79715d95f1894771eb4e60fb23f065663b2298f7d22945d66877aadf33d00c7", size = 6640743, upload-time = "2025-09-09T15:57:07.921Z" }, + { url = "https://files.pythonhosted.org/packages/23/83/377f84aaeb800b64c0ef4de58b08769e782edcefa4fea712910b6f0afd3c/numpy-2.3.3-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:952cfd0748514ea7c3afc729a0fc639e61655ce4c55ab9acfab14bda4f402b4c", size = 14278881, upload-time = "2025-09-09T15:57:11.349Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a5/bf3db6e66c4b160d6ea10b534c381a1955dfab34cb1017ea93aa33c70ed3/numpy-2.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5b83648633d46f77039c29078751f80da65aa64d5622a3cd62aaef9d835b6c93", size = 16636301, upload-time = "2025-09-09T15:57:14.245Z" }, + { url = "https://files.pythonhosted.org/packages/a2/59/1287924242eb4fa3f9b3a2c30400f2e17eb2707020d1c5e3086fe7330717/numpy-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b001bae8cea1c7dfdb2ae2b017ed0a6f2102d7a70059df1e338e307a4c78a8ae", size = 16053645, upload-time = "2025-09-09T15:57:16.534Z" }, + { url = "https://files.pythonhosted.org/packages/e6/93/b3d47ed882027c35e94ac2320c37e452a549f582a5e801f2d34b56973c97/numpy-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8e9aced64054739037d42fb84c54dd38b81ee238816c948c8f3ed134665dcd86", size = 18578179, upload-time = "2025-09-09T15:57:18.883Z" }, + { url = "https://files.pythonhosted.org/packages/20/d9/487a2bccbf7cc9d4bfc5f0f197761a5ef27ba870f1e3bbb9afc4bbe3fcc2/numpy-2.3.3-cp313-cp313-win32.whl", hash = "sha256:9591e1221db3f37751e6442850429b3aabf7026d3b05542d102944ca7f00c8a8", size = 6312250, upload-time = "2025-09-09T15:57:21.296Z" }, + { url = "https://files.pythonhosted.org/packages/1b/b5/263ebbbbcede85028f30047eab3d58028d7ebe389d6493fc95ae66c636ab/numpy-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f0dadeb302887f07431910f67a14d57209ed91130be0adea2f9793f1a4f817cf", size = 12783269, upload-time = "2025-09-09T15:57:23.034Z" }, + { url = "https://files.pythonhosted.org/packages/fa/75/67b8ca554bbeaaeb3fac2e8bce46967a5a06544c9108ec0cf5cece559b6c/numpy-2.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:3c7cf302ac6e0b76a64c4aecf1a09e51abd9b01fc7feee80f6c43e3ab1b1dbc5", size = 10195314, upload-time = "2025-09-09T15:57:25.045Z" }, + { url = "https://files.pythonhosted.org/packages/11/d0/0d1ddec56b162042ddfafeeb293bac672de9b0cfd688383590090963720a/numpy-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:eda59e44957d272846bb407aad19f89dc6f58fecf3504bd144f4c5cf81a7eacc", size = 21048025, upload-time = "2025-09-09T15:57:27.257Z" }, + { url = "https://files.pythonhosted.org/packages/36/9e/1996ca6b6d00415b6acbdd3c42f7f03ea256e2c3f158f80bd7436a8a19f3/numpy-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:823d04112bc85ef5c4fda73ba24e6096c8f869931405a80aa8b0e604510a26bc", size = 14301053, upload-time = "2025-09-09T15:57:30.077Z" }, + { url = "https://files.pythonhosted.org/packages/05/24/43da09aa764c68694b76e84b3d3f0c44cb7c18cdc1ba80e48b0ac1d2cd39/numpy-2.3.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:40051003e03db4041aa325da2a0971ba41cf65714e65d296397cc0e32de6018b", size = 5229444, upload-time = "2025-09-09T15:57:32.733Z" }, + { url = "https://files.pythonhosted.org/packages/bc/14/50ffb0f22f7218ef8af28dd089f79f68289a7a05a208db9a2c5dcbe123c1/numpy-2.3.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:6ee9086235dd6ab7ae75aba5662f582a81ced49f0f1c6de4260a78d8f2d91a19", size = 6738039, upload-time = "2025-09-09T15:57:34.328Z" }, + { url = "https://files.pythonhosted.org/packages/55/52/af46ac0795e09657d45a7f4db961917314377edecf66db0e39fa7ab5c3d3/numpy-2.3.3-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:94fcaa68757c3e2e668ddadeaa86ab05499a70725811e582b6a9858dd472fb30", size = 14352314, upload-time = "2025-09-09T15:57:36.255Z" }, + { url = "https://files.pythonhosted.org/packages/a7/b1/dc226b4c90eb9f07a3fff95c2f0db3268e2e54e5cce97c4ac91518aee71b/numpy-2.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:da1a74b90e7483d6ce5244053399a614b1d6b7bc30a60d2f570e5071f8959d3e", size = 16701722, upload-time = "2025-09-09T15:57:38.622Z" }, + { url = "https://files.pythonhosted.org/packages/9d/9d/9d8d358f2eb5eced14dba99f110d83b5cd9a4460895230f3b396ad19a323/numpy-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2990adf06d1ecee3b3dcbb4977dfab6e9f09807598d647f04d385d29e7a3c3d3", size = 16132755, upload-time = "2025-09-09T15:57:41.16Z" }, + { url = "https://files.pythonhosted.org/packages/b6/27/b3922660c45513f9377b3fb42240bec63f203c71416093476ec9aa0719dc/numpy-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ed635ff692483b8e3f0fcaa8e7eb8a75ee71aa6d975388224f70821421800cea", size = 18651560, upload-time = "2025-09-09T15:57:43.459Z" }, + { url = "https://files.pythonhosted.org/packages/5b/8e/3ab61a730bdbbc201bb245a71102aa609f0008b9ed15255500a99cd7f780/numpy-2.3.3-cp313-cp313t-win32.whl", hash = "sha256:a333b4ed33d8dc2b373cc955ca57babc00cd6f9009991d9edc5ddbc1bac36bcd", size = 6442776, upload-time = "2025-09-09T15:57:45.793Z" }, + { url = "https://files.pythonhosted.org/packages/1c/3a/e22b766b11f6030dc2decdeff5c2fb1610768055603f9f3be88b6d192fb2/numpy-2.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:4384a169c4d8f97195980815d6fcad04933a7e1ab3b530921c3fef7a1c63426d", size = 12927281, upload-time = "2025-09-09T15:57:47.492Z" }, + { url = "https://files.pythonhosted.org/packages/7b/42/c2e2bc48c5e9b2a83423f99733950fbefd86f165b468a3d85d52b30bf782/numpy-2.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:75370986cc0bc66f4ce5110ad35aae6d182cc4ce6433c40ad151f53690130bf1", size = 10265275, upload-time = "2025-09-09T15:57:49.647Z" }, + { url = "https://files.pythonhosted.org/packages/b8/f2/7e0a37cfced2644c9563c529f29fa28acbd0960dde32ece683aafa6f4949/numpy-2.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1e02c7159791cd481e1e6d5ddd766b62a4d5acf8df4d4d1afe35ee9c5c33a41e", size = 21131019, upload-time = "2025-09-09T15:58:42.838Z" }, + { url = "https://files.pythonhosted.org/packages/1a/7e/3291f505297ed63831135a6cc0f474da0c868a1f31b0dd9a9f03a7a0d2ed/numpy-2.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:dca2d0fc80b3893ae72197b39f69d55a3cd8b17ea1b50aa4c62de82419936150", size = 14376288, upload-time = "2025-09-09T15:58:45.425Z" }, + { url = "https://files.pythonhosted.org/packages/bf/4b/ae02e985bdeee73d7b5abdefeb98aef1207e96d4c0621ee0cf228ddfac3c/numpy-2.3.3-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:99683cbe0658f8271b333a1b1b4bb3173750ad59c0c61f5bbdc5b318918fffe3", size = 5305425, upload-time = "2025-09-09T15:58:48.6Z" }, + { url = "https://files.pythonhosted.org/packages/8b/eb/9df215d6d7250db32007941500dc51c48190be25f2401d5b2b564e467247/numpy-2.3.3-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:d9d537a39cc9de668e5cd0e25affb17aec17b577c6b3ae8a3d866b479fbe88d0", size = 6819053, upload-time = "2025-09-09T15:58:50.401Z" }, + { url = "https://files.pythonhosted.org/packages/57/62/208293d7d6b2a8998a4a1f23ac758648c3c32182d4ce4346062018362e29/numpy-2.3.3-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8596ba2f8af5f93b01d97563832686d20206d303024777f6dfc2e7c7c3f1850e", size = 14420354, upload-time = "2025-09-09T15:58:52.704Z" }, + { url = "https://files.pythonhosted.org/packages/ed/0c/8e86e0ff7072e14a71b4c6af63175e40d1e7e933ce9b9e9f765a95b4e0c3/numpy-2.3.3-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1ec5615b05369925bd1125f27df33f3b6c8bc10d788d5999ecd8769a1fa04db", size = 16760413, upload-time = "2025-09-09T15:58:55.027Z" }, + { url = "https://files.pythonhosted.org/packages/af/11/0cc63f9f321ccf63886ac203336777140011fb669e739da36d8db3c53b98/numpy-2.3.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:2e267c7da5bf7309670523896df97f93f6e469fb931161f483cd6882b3b1a5dc", size = 12971844, upload-time = "2025-09-09T15:58:57.359Z" }, ] [[package]] name = "numpy-typing-compat" -version = "20250818.2.2" +version = "20250818.2.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d5/2c/6312cfc304b141bf9fa25a73dcd37d74a96cf411f0aa0f6df11f83e0b0ee/numpy_typing_compat-20250818.2.2.tar.gz", hash = "sha256:84f50c86908bf796857180856f1acb7da3c5bf22f461558de1cd225128c028ba", size = 4981, upload-time = "2025-08-18T23:46:42.17Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/e3/1a29f174c1e09a2bf111d37a41afceea1b501371abb39e73170ca31a7599/numpy_typing_compat-20250818.2.3.tar.gz", hash = "sha256:72e83d535b635d668ba7315e43ae80be1469a6faea6fc96d312516f39b3d8fa5", size = 4974, upload-time = "2025-08-18T23:46:42.968Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f3/36/4093816a4614df4d99ba71010736f1122acc2dbae316373575f17aaa2f8e/numpy_typing_compat-20250818.2.2-py3-none-any.whl", hash = "sha256:8b6c551952fd46e887ee905e75b6e4977d97defe1c63ae1b516343e9913e1534", size = 6292, upload-time = "2025-08-18T23:46:34.175Z" }, + { url = "https://files.pythonhosted.org/packages/c9/4a/fa4c90a03d6a8ee1a7f0e0fb101887d9a8cdb9b07a5901af9ae831e9feea/numpy_typing_compat-20250818.2.3-py3-none-any.whl", hash = "sha256:930413d34dd9083c0bf418815576222f1c66ea2d68950f447fd27ea1a78b26b0", size = 6286, upload-time = "2025-08-18T23:46:35.681Z" }, ] [[package]] @@ -2051,7 +2049,7 @@ wheels = [ [[package]] name = "pandas" -version = "2.3.2" +version = "2.3.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, @@ -2059,48 +2057,48 @@ dependencies = [ { name = "pytz" }, { name = "tzdata" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/79/8e/0e90233ac205ad182bd6b422532695d2b9414944a280488105d598c70023/pandas-2.3.2.tar.gz", hash = "sha256:ab7b58f8f82706890924ccdfb5f48002b83d2b5a3845976a9fb705d36c34dcdb", size = 4488684, upload-time = "2025-08-21T10:28:29.257Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7a/59/f3e010879f118c2d400902d2d871c2226cef29b08c09fb8dc41111730400/pandas-2.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1333e9c299adcbb68ee89a9bb568fc3f20f9cbb419f1dd5225071e6cddb2a743", size = 11563308, upload-time = "2025-08-21T10:26:56.656Z" }, - { url = "https://files.pythonhosted.org/packages/38/18/48f10f1cc5c397af59571d638d211f494dba481f449c19adbd282aa8f4ca/pandas-2.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:76972bcbd7de8e91ad5f0ca884a9f2c477a2125354af624e022c49e5bd0dfff4", size = 10820319, upload-time = "2025-08-21T10:26:59.162Z" }, - { url = "https://files.pythonhosted.org/packages/95/3b/1e9b69632898b048e223834cd9702052bcf06b15e1ae716eda3196fb972e/pandas-2.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b98bdd7c456a05eef7cd21fd6b29e3ca243591fe531c62be94a2cc987efb5ac2", size = 11790097, upload-time = "2025-08-21T10:27:02.204Z" }, - { url = "https://files.pythonhosted.org/packages/8b/ef/0e2ffb30b1f7fbc9a588bd01e3c14a0d96854d09a887e15e30cc19961227/pandas-2.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d81573b3f7db40d020983f78721e9bfc425f411e616ef019a10ebf597aedb2e", size = 12397958, upload-time = "2025-08-21T10:27:05.409Z" }, - { url = "https://files.pythonhosted.org/packages/23/82/e6b85f0d92e9afb0e7f705a51d1399b79c7380c19687bfbf3d2837743249/pandas-2.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e190b738675a73b581736cc8ec71ae113d6c3768d0bd18bffa5b9a0927b0b6ea", size = 13225600, upload-time = "2025-08-21T10:27:07.791Z" }, - { url = "https://files.pythonhosted.org/packages/e8/f1/f682015893d9ed51611948bd83683670842286a8edd4f68c2c1c3b231eef/pandas-2.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c253828cb08f47488d60f43c5fc95114c771bbfff085da54bfc79cb4f9e3a372", size = 13879433, upload-time = "2025-08-21T10:27:10.347Z" }, - { url = "https://files.pythonhosted.org/packages/a7/e7/ae86261695b6c8a36d6a4c8d5f9b9ede8248510d689a2f379a18354b37d7/pandas-2.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:9467697b8083f9667b212633ad6aa4ab32436dcbaf4cd57325debb0ddef2012f", size = 11336557, upload-time = "2025-08-21T10:27:12.983Z" }, - { url = "https://files.pythonhosted.org/packages/ec/db/614c20fb7a85a14828edd23f1c02db58a30abf3ce76f38806155d160313c/pandas-2.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3fbb977f802156e7a3f829e9d1d5398f6192375a3e2d1a9ee0803e35fe70a2b9", size = 11587652, upload-time = "2025-08-21T10:27:15.888Z" }, - { url = "https://files.pythonhosted.org/packages/99/b0/756e52f6582cade5e746f19bad0517ff27ba9c73404607c0306585c201b3/pandas-2.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1b9b52693123dd234b7c985c68b709b0b009f4521000d0525f2b95c22f15944b", size = 10717686, upload-time = "2025-08-21T10:27:18.486Z" }, - { url = "https://files.pythonhosted.org/packages/37/4c/dd5ccc1e357abfeee8353123282de17997f90ff67855f86154e5a13b81e5/pandas-2.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bd281310d4f412733f319a5bc552f86d62cddc5f51d2e392c8787335c994175", size = 11278722, upload-time = "2025-08-21T10:27:21.149Z" }, - { url = "https://files.pythonhosted.org/packages/d3/a4/f7edcfa47e0a88cda0be8b068a5bae710bf264f867edfdf7b71584ace362/pandas-2.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96d31a6b4354e3b9b8a2c848af75d31da390657e3ac6f30c05c82068b9ed79b9", size = 11987803, upload-time = "2025-08-21T10:27:23.767Z" }, - { url = "https://files.pythonhosted.org/packages/f6/61/1bce4129f93ab66f1c68b7ed1c12bac6a70b1b56c5dab359c6bbcd480b52/pandas-2.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:df4df0b9d02bb873a106971bb85d448378ef14b86ba96f035f50bbd3688456b4", size = 12766345, upload-time = "2025-08-21T10:27:26.6Z" }, - { url = "https://files.pythonhosted.org/packages/8e/46/80d53de70fee835531da3a1dae827a1e76e77a43ad22a8cd0f8142b61587/pandas-2.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:213a5adf93d020b74327cb2c1b842884dbdd37f895f42dcc2f09d451d949f811", size = 13439314, upload-time = "2025-08-21T10:27:29.213Z" }, - { url = "https://files.pythonhosted.org/packages/28/30/8114832daff7489f179971dbc1d854109b7f4365a546e3ea75b6516cea95/pandas-2.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:8c13b81a9347eb8c7548f53fd9a4f08d4dfe996836543f805c987bafa03317ae", size = 10983326, upload-time = "2025-08-21T10:27:31.901Z" }, - { url = "https://files.pythonhosted.org/packages/27/64/a2f7bf678af502e16b472527735d168b22b7824e45a4d7e96a4fbb634b59/pandas-2.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0c6ecbac99a354a051ef21c5307601093cb9e0f4b1855984a084bfec9302699e", size = 11531061, upload-time = "2025-08-21T10:27:34.647Z" }, - { url = "https://files.pythonhosted.org/packages/54/4c/c3d21b2b7769ef2f4c2b9299fcadd601efa6729f1357a8dbce8dd949ed70/pandas-2.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c6f048aa0fd080d6a06cc7e7537c09b53be6642d330ac6f54a600c3ace857ee9", size = 10668666, upload-time = "2025-08-21T10:27:37.203Z" }, - { url = "https://files.pythonhosted.org/packages/50/e2/f775ba76ecfb3424d7f5862620841cf0edb592e9abd2d2a5387d305fe7a8/pandas-2.3.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0064187b80a5be6f2f9c9d6bdde29372468751dfa89f4211a3c5871854cfbf7a", size = 11332835, upload-time = "2025-08-21T10:27:40.188Z" }, - { url = "https://files.pythonhosted.org/packages/8f/52/0634adaace9be2d8cac9ef78f05c47f3a675882e068438b9d7ec7ef0c13f/pandas-2.3.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ac8c320bded4718b298281339c1a50fb00a6ba78cb2a63521c39bec95b0209b", size = 12057211, upload-time = "2025-08-21T10:27:43.117Z" }, - { url = "https://files.pythonhosted.org/packages/0b/9d/2df913f14b2deb9c748975fdb2491da1a78773debb25abbc7cbc67c6b549/pandas-2.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:114c2fe4f4328cf98ce5716d1532f3ab79c5919f95a9cfee81d9140064a2e4d6", size = 12749277, upload-time = "2025-08-21T10:27:45.474Z" }, - { url = "https://files.pythonhosted.org/packages/87/af/da1a2417026bd14d98c236dba88e39837182459d29dcfcea510b2ac9e8a1/pandas-2.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:48fa91c4dfb3b2b9bfdb5c24cd3567575f4e13f9636810462ffed8925352be5a", size = 13415256, upload-time = "2025-08-21T10:27:49.885Z" }, - { url = "https://files.pythonhosted.org/packages/22/3c/f2af1ce8840ef648584a6156489636b5692c162771918aa95707c165ad2b/pandas-2.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:12d039facec710f7ba305786837d0225a3444af7bbd9c15c32ca2d40d157ed8b", size = 10982579, upload-time = "2025-08-21T10:28:08.435Z" }, - { url = "https://files.pythonhosted.org/packages/f3/98/8df69c4097a6719e357dc249bf437b8efbde808038268e584421696cbddf/pandas-2.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:c624b615ce97864eb588779ed4046186f967374185c047070545253a52ab2d57", size = 12028163, upload-time = "2025-08-21T10:27:52.232Z" }, - { url = "https://files.pythonhosted.org/packages/0e/23/f95cbcbea319f349e10ff90db488b905c6883f03cbabd34f6b03cbc3c044/pandas-2.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0cee69d583b9b128823d9514171cabb6861e09409af805b54459bd0c821a35c2", size = 11391860, upload-time = "2025-08-21T10:27:54.673Z" }, - { url = "https://files.pythonhosted.org/packages/ad/1b/6a984e98c4abee22058aa75bfb8eb90dce58cf8d7296f8bc56c14bc330b0/pandas-2.3.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2319656ed81124982900b4c37f0e0c58c015af9a7bbc62342ba5ad07ace82ba9", size = 11309830, upload-time = "2025-08-21T10:27:56.957Z" }, - { url = "https://files.pythonhosted.org/packages/15/d5/f0486090eb18dd8710bf60afeaf638ba6817047c0c8ae5c6a25598665609/pandas-2.3.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b37205ad6f00d52f16b6d09f406434ba928c1a1966e2771006a9033c736d30d2", size = 11883216, upload-time = "2025-08-21T10:27:59.302Z" }, - { url = "https://files.pythonhosted.org/packages/10/86/692050c119696da19e20245bbd650d8dfca6ceb577da027c3a73c62a047e/pandas-2.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:837248b4fc3a9b83b9c6214699a13f069dc13510a6a6d7f9ba33145d2841a012", size = 12699743, upload-time = "2025-08-21T10:28:02.447Z" }, - { url = "https://files.pythonhosted.org/packages/cd/d7/612123674d7b17cf345aad0a10289b2a384bff404e0463a83c4a3a59d205/pandas-2.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d2c3554bd31b731cd6490d94a28f3abb8dd770634a9e06eb6d2911b9827db370", size = 13186141, upload-time = "2025-08-21T10:28:05.377Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload-time = "2025-09-29T23:34:51.853Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/fa/7ac648108144a095b4fb6aa3de1954689f7af60a14cf25583f4960ecb878/pandas-2.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:602b8615ebcc4a0c1751e71840428ddebeb142ec02c786e8ad6b1ce3c8dec523", size = 11578790, upload-time = "2025-09-29T23:18:30.065Z" }, + { url = "https://files.pythonhosted.org/packages/9b/35/74442388c6cf008882d4d4bdfc4109be87e9b8b7ccd097ad1e7f006e2e95/pandas-2.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8fe25fc7b623b0ef6b5009149627e34d2a4657e880948ec3c840e9402e5c1b45", size = 10833831, upload-time = "2025-09-29T23:38:56.071Z" }, + { url = "https://files.pythonhosted.org/packages/fe/e4/de154cbfeee13383ad58d23017da99390b91d73f8c11856f2095e813201b/pandas-2.3.3-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b468d3dad6ff947df92dcb32ede5b7bd41a9b3cceef0a30ed925f6d01fb8fa66", size = 12199267, upload-time = "2025-09-29T23:18:41.627Z" }, + { url = "https://files.pythonhosted.org/packages/bf/c9/63f8d545568d9ab91476b1818b4741f521646cbdd151c6efebf40d6de6f7/pandas-2.3.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b98560e98cb334799c0b07ca7967ac361a47326e9b4e5a7dfb5ab2b1c9d35a1b", size = 12789281, upload-time = "2025-09-29T23:18:56.834Z" }, + { url = "https://files.pythonhosted.org/packages/f2/00/a5ac8c7a0e67fd1a6059e40aa08fa1c52cc00709077d2300e210c3ce0322/pandas-2.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37b5848ba49824e5c30bedb9c830ab9b7751fd049bc7914533e01c65f79791", size = 13240453, upload-time = "2025-09-29T23:19:09.247Z" }, + { url = "https://files.pythonhosted.org/packages/27/4d/5c23a5bc7bd209231618dd9e606ce076272c9bc4f12023a70e03a86b4067/pandas-2.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:db4301b2d1f926ae677a751eb2bd0e8c5f5319c9cb3f88b0becbbb0b07b34151", size = 13890361, upload-time = "2025-09-29T23:19:25.342Z" }, + { url = "https://files.pythonhosted.org/packages/8e/59/712db1d7040520de7a4965df15b774348980e6df45c129b8c64d0dbe74ef/pandas-2.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:f086f6fe114e19d92014a1966f43a3e62285109afe874f067f5abbdcbb10e59c", size = 11348702, upload-time = "2025-09-29T23:19:38.296Z" }, + { url = "https://files.pythonhosted.org/packages/9c/fb/231d89e8637c808b997d172b18e9d4a4bc7bf31296196c260526055d1ea0/pandas-2.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d21f6d74eb1725c2efaa71a2bfc661a0689579b58e9c0ca58a739ff0b002b53", size = 11597846, upload-time = "2025-09-29T23:19:48.856Z" }, + { url = "https://files.pythonhosted.org/packages/5c/bd/bf8064d9cfa214294356c2d6702b716d3cf3bb24be59287a6a21e24cae6b/pandas-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3fd2f887589c7aa868e02632612ba39acb0b8948faf5cc58f0850e165bd46f35", size = 10729618, upload-time = "2025-09-29T23:39:08.659Z" }, + { url = "https://files.pythonhosted.org/packages/57/56/cf2dbe1a3f5271370669475ead12ce77c61726ffd19a35546e31aa8edf4e/pandas-2.3.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecaf1e12bdc03c86ad4a7ea848d66c685cb6851d807a26aa245ca3d2017a1908", size = 11737212, upload-time = "2025-09-29T23:19:59.765Z" }, + { url = "https://files.pythonhosted.org/packages/e5/63/cd7d615331b328e287d8233ba9fdf191a9c2d11b6af0c7a59cfcec23de68/pandas-2.3.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b3d11d2fda7eb164ef27ffc14b4fcab16a80e1ce67e9f57e19ec0afaf715ba89", size = 12362693, upload-time = "2025-09-29T23:20:14.098Z" }, + { url = "https://files.pythonhosted.org/packages/a6/de/8b1895b107277d52f2b42d3a6806e69cfef0d5cf1d0ba343470b9d8e0a04/pandas-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a68e15f780eddf2b07d242e17a04aa187a7ee12b40b930bfdd78070556550e98", size = 12771002, upload-time = "2025-09-29T23:20:26.76Z" }, + { url = "https://files.pythonhosted.org/packages/87/21/84072af3187a677c5893b170ba2c8fbe450a6ff911234916da889b698220/pandas-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:371a4ab48e950033bcf52b6527eccb564f52dc826c02afd9a1bc0ab731bba084", size = 13450971, upload-time = "2025-09-29T23:20:41.344Z" }, + { url = "https://files.pythonhosted.org/packages/86/41/585a168330ff063014880a80d744219dbf1dd7a1c706e75ab3425a987384/pandas-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:a16dcec078a01eeef8ee61bf64074b4e524a2a3f4b3be9326420cabe59c4778b", size = 10992722, upload-time = "2025-09-29T23:20:54.139Z" }, + { url = "https://files.pythonhosted.org/packages/cd/4b/18b035ee18f97c1040d94debd8f2e737000ad70ccc8f5513f4eefad75f4b/pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713", size = 11544671, upload-time = "2025-09-29T23:21:05.024Z" }, + { url = "https://files.pythonhosted.org/packages/31/94/72fac03573102779920099bcac1c3b05975c2cb5f01eac609faf34bed1ca/pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8", size = 10680807, upload-time = "2025-09-29T23:21:15.979Z" }, + { url = "https://files.pythonhosted.org/packages/16/87/9472cf4a487d848476865321de18cc8c920b8cab98453ab79dbbc98db63a/pandas-2.3.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d", size = 11709872, upload-time = "2025-09-29T23:21:27.165Z" }, + { url = "https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac", size = 12306371, upload-time = "2025-09-29T23:21:40.532Z" }, + { url = "https://files.pythonhosted.org/packages/33/81/a3afc88fca4aa925804a27d2676d22dcd2031c2ebe08aabd0ae55b9ff282/pandas-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c", size = 12765333, upload-time = "2025-09-29T23:21:55.77Z" }, + { url = "https://files.pythonhosted.org/packages/8d/0f/b4d4ae743a83742f1153464cf1a8ecfafc3ac59722a0b5c8602310cb7158/pandas-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493", size = 13418120, upload-time = "2025-09-29T23:22:10.109Z" }, + { url = "https://files.pythonhosted.org/packages/4f/c7/e54682c96a895d0c808453269e0b5928a07a127a15704fedb643e9b0a4c8/pandas-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee", size = 10993991, upload-time = "2025-09-29T23:25:04.889Z" }, + { url = "https://files.pythonhosted.org/packages/f9/ca/3f8d4f49740799189e1395812f3bf23b5e8fc7c190827d55a610da72ce55/pandas-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5", size = 12048227, upload-time = "2025-09-29T23:22:24.343Z" }, + { url = "https://files.pythonhosted.org/packages/0e/5a/f43efec3e8c0cc92c4663ccad372dbdff72b60bdb56b2749f04aa1d07d7e/pandas-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21", size = 11411056, upload-time = "2025-09-29T23:22:37.762Z" }, + { url = "https://files.pythonhosted.org/packages/46/b1/85331edfc591208c9d1a63a06baa67b21d332e63b7a591a5ba42a10bb507/pandas-2.3.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78", size = 11645189, upload-time = "2025-09-29T23:22:51.688Z" }, + { url = "https://files.pythonhosted.org/packages/44/23/78d645adc35d94d1ac4f2a3c4112ab6f5b8999f4898b8cdf01252f8df4a9/pandas-2.3.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110", size = 12121912, upload-time = "2025-09-29T23:23:05.042Z" }, + { url = "https://files.pythonhosted.org/packages/53/da/d10013df5e6aaef6b425aa0c32e1fc1f3e431e4bcabd420517dceadce354/pandas-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86", size = 12712160, upload-time = "2025-09-29T23:23:28.57Z" }, + { url = "https://files.pythonhosted.org/packages/bd/17/e756653095a083d8a37cbd816cb87148debcfcd920129b25f99dd8d04271/pandas-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc", size = 13199233, upload-time = "2025-09-29T23:24:24.876Z" }, ] [[package]] name = "pandas-stubs" -version = "2.3.2.250827" +version = "2.3.2.250926" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, { name = "types-pytz" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/03/7b/8d2076a76ddf35806319798037056e4bbdcacdc832fb7c95b517f4c03fb2/pandas_stubs-2.3.2.250827.tar.gz", hash = "sha256:bcc2d49a2766325e4a1a492c3eeda879e9521bb5e26e69e2bbf13e80e7ef569a", size = 100032, upload-time = "2025-08-27T23:18:12.802Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1b/3b/32be58a125db39d0b5f62cc93795f32b5bb2915bd5c4a46f0e35171985e2/pandas_stubs-2.3.2.250926.tar.gz", hash = "sha256:c64b9932760ceefb96a3222b953e6a251321a9832a28548be6506df473a66406", size = 102147, upload-time = "2025-09-26T19:50:39.522Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a1/b8/dc820157be5aa9527f1f7ffe81737ee4d1cf0924081e1bfbd680530dde41/pandas_stubs-2.3.2.250827-py3-none-any.whl", hash = "sha256:3d613013b4189147a9a6bb18d8bec1e5b137de091496e9b9ff9f137ec3e223a9", size = 157775, upload-time = "2025-08-27T23:18:11.083Z" }, + { url = "https://files.pythonhosted.org/packages/40/96/1e4a035eaf4dce9610aac6e43026d0c6baa05773daf6d21e635a4fe19e21/pandas_stubs-2.3.2.250926-py3-none-any.whl", hash = "sha256:81121818453dcfe00f45c852f4dceee043640b813830f6e7bd084a4ef7ff7270", size = 159995, upload-time = "2025-09-26T19:50:38.241Z" }, ] [[package]] @@ -2285,38 +2283,39 @@ wheels = [ [[package]] name = "prometheus-client" -version = "0.22.1" +version = "0.23.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5e/cf/40dde0a2be27cc1eb41e333d1a674a74ce8b8b0457269cc640fd42b07cf7/prometheus_client-0.22.1.tar.gz", hash = "sha256:190f1331e783cf21eb60bca559354e0a4d4378facecf78f5428c39b675d20d28", size = 69746, upload-time = "2025-06-02T14:29:01.152Z" } +sdist = { url = "https://files.pythonhosted.org/packages/23/53/3edb5d68ecf6b38fcbcc1ad28391117d2a322d9a1a3eff04bfdb184d8c3b/prometheus_client-0.23.1.tar.gz", hash = "sha256:6ae8f9081eaaaf153a2e959d2e6c4f4fb57b12ef76c8c7980202f1e57b48b2ce", size = 80481, upload-time = "2025-09-18T20:47:25.043Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/32/ae/ec06af4fe3ee72d16973474f122541746196aaa16cea6f66d18b963c6177/prometheus_client-0.22.1-py3-none-any.whl", hash = "sha256:cca895342e308174341b2cbf99a56bef291fbc0ef7b9e5412a0f26d653ba7094", size = 58694, upload-time = "2025-06-02T14:29:00.068Z" }, + { url = "https://files.pythonhosted.org/packages/b8/db/14bafcb4af2139e046d03fd00dea7873e48eafe18b7d2797e73d6681f210/prometheus_client-0.23.1-py3-none-any.whl", hash = "sha256:dd1913e6e76b59cfe44e7a4b83e01afc9873c1bdfd2ed8739f1e76aeca115f99", size = 61145, upload-time = "2025-09-18T20:47:23.875Z" }, ] [[package]] name = "prompt-toolkit" -version = "3.0.52" +version = "3.0.51" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "wcwidth" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a1/96/06e01a7b38dce6fe1db213e061a4602dd6032a8a97ef6c1a862537732421/prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855", size = 434198, upload-time = "2025-08-27T15:24:02.057Z" } +sdist = { url = "https://files.pythonhosted.org/packages/bb/6e/9d084c929dfe9e3bfe0c6a47e31f78a25c54627d64a66e884a8bf5474f1c/prompt_toolkit-3.0.51.tar.gz", hash = "sha256:931a162e3b27fc90c86f1b48bb1fb2c528c2761475e57c9c06de13311c7b54ed", size = 428940, upload-time = "2025-04-15T09:18:47.731Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955", size = 391431, upload-time = "2025-08-27T15:23:59.498Z" }, + { url = "https://files.pythonhosted.org/packages/ce/4f/5249960887b1fbe561d9ff265496d170b55a735b76724f10ef19f9e40716/prompt_toolkit-3.0.51-py3-none-any.whl", hash = "sha256:52742911fde84e2d423e2f9a4cf1de7d7ac4e51958f648d9540e0fb8db077b07", size = 387810, upload-time = "2025-04-15T09:18:44.753Z" }, ] [[package]] name = "psutil" -version = "7.0.0" +version = "7.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2a/80/336820c1ad9286a4ded7e845b2eccfcb27851ab8ac6abece774a6ff4d3de/psutil-7.0.0.tar.gz", hash = "sha256:7be9c3eba38beccb6495ea33afd982a44074b78f28c434a1f51cc07fd315c456", size = 497003, upload-time = "2025-02-13T21:54:07.946Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b3/31/4723d756b59344b643542936e37a31d1d3204bcdc42a7daa8ee9eb06fb50/psutil-7.1.0.tar.gz", hash = "sha256:655708b3c069387c8b77b072fc429a57d0e214221d01c0a772df7dfedcb3bcd2", size = 497660, upload-time = "2025-09-17T20:14:52.902Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ed/e6/2d26234410f8b8abdbf891c9da62bee396583f713fb9f3325a4760875d22/psutil-7.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:101d71dc322e3cffd7cea0650b09b3d08b8e7c4109dd6809fe452dfd00e58b25", size = 238051, upload-time = "2025-02-13T21:54:12.36Z" }, - { url = "https://files.pythonhosted.org/packages/04/8b/30f930733afe425e3cbfc0e1468a30a18942350c1a8816acfade80c005c4/psutil-7.0.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:39db632f6bb862eeccf56660871433e111b6ea58f2caea825571951d4b6aa3da", size = 239535, upload-time = "2025-02-13T21:54:16.07Z" }, - { url = "https://files.pythonhosted.org/packages/2a/ed/d362e84620dd22876b55389248e522338ed1bf134a5edd3b8231d7207f6d/psutil-7.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fcee592b4c6f146991ca55919ea3d1f8926497a713ed7faaf8225e174581e91", size = 275004, upload-time = "2025-02-13T21:54:18.662Z" }, - { url = "https://files.pythonhosted.org/packages/bf/b9/b0eb3f3cbcb734d930fdf839431606844a825b23eaf9a6ab371edac8162c/psutil-7.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b1388a4f6875d7e2aff5c4ca1cc16c545ed41dd8bb596cefea80111db353a34", size = 277986, upload-time = "2025-02-13T21:54:21.811Z" }, - { url = "https://files.pythonhosted.org/packages/eb/a2/709e0fe2f093556c17fbafda93ac032257242cabcc7ff3369e2cb76a97aa/psutil-7.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5f098451abc2828f7dc6b58d44b532b22f2088f4999a937557b603ce72b1993", size = 279544, upload-time = "2025-02-13T21:54:24.68Z" }, - { url = "https://files.pythonhosted.org/packages/50/e6/eecf58810b9d12e6427369784efe814a1eec0f492084ce8eb8f4d89d6d61/psutil-7.0.0-cp37-abi3-win32.whl", hash = "sha256:ba3fcef7523064a6c9da440fc4d6bd07da93ac726b5733c29027d7dc95b39d99", size = 241053, upload-time = "2025-02-13T21:54:34.31Z" }, - { url = "https://files.pythonhosted.org/packages/50/1b/6921afe68c74868b4c9fa424dad3be35b095e16687989ebbb50ce4fceb7c/psutil-7.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:4cf3d4eb1aa9b348dec30105c55cd9b7d4629285735a102beb4441e38db90553", size = 244885, upload-time = "2025-02-13T21:54:37.486Z" }, + { url = "https://files.pythonhosted.org/packages/46/62/ce4051019ee20ce0ed74432dd73a5bb087a6704284a470bb8adff69a0932/psutil-7.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:76168cef4397494250e9f4e73eb3752b146de1dd950040b29186d0cce1d5ca13", size = 245242, upload-time = "2025-09-17T20:14:56.126Z" }, + { url = "https://files.pythonhosted.org/packages/38/61/f76959fba841bf5b61123fbf4b650886dc4094c6858008b5bf73d9057216/psutil-7.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:5d007560c8c372efdff9e4579c2846d71de737e4605f611437255e81efcca2c5", size = 246682, upload-time = "2025-09-17T20:14:58.25Z" }, + { url = "https://files.pythonhosted.org/packages/88/7a/37c99d2e77ec30d63398ffa6a660450b8a62517cabe44b3e9bae97696e8d/psutil-7.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22e4454970b32472ce7deaa45d045b34d3648ce478e26a04c7e858a0a6e75ff3", size = 287994, upload-time = "2025-09-17T20:14:59.901Z" }, + { url = "https://files.pythonhosted.org/packages/9d/de/04c8c61232f7244aa0a4b9a9fbd63a89d5aeaf94b2fc9d1d16e2faa5cbb0/psutil-7.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c70e113920d51e89f212dd7be06219a9b88014e63a4cec69b684c327bc474e3", size = 291163, upload-time = "2025-09-17T20:15:01.481Z" }, + { url = "https://files.pythonhosted.org/packages/f4/58/c4f976234bf6d4737bc8c02a81192f045c307b72cf39c9e5c5a2d78927f6/psutil-7.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d4a113425c037300de3ac8b331637293da9be9713855c4fc9d2d97436d7259d", size = 293625, upload-time = "2025-09-17T20:15:04.492Z" }, + { url = "https://files.pythonhosted.org/packages/79/87/157c8e7959ec39ced1b11cc93c730c4fb7f9d408569a6c59dbd92ceb35db/psutil-7.1.0-cp37-abi3-win32.whl", hash = "sha256:09ad740870c8d219ed8daae0ad3b726d3bf9a028a198e7f3080f6a1888b99bca", size = 244812, upload-time = "2025-09-17T20:15:07.462Z" }, + { url = "https://files.pythonhosted.org/packages/bf/e9/b44c4f697276a7a95b8e94d0e320a7bf7f3318521b23de69035540b39838/psutil-7.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:57f5e987c36d3146c0dd2528cd42151cf96cd359b9d67cfff836995cc5df9a3d", size = 247965, upload-time = "2025-09-17T20:15:09.673Z" }, + { url = "https://files.pythonhosted.org/packages/26/65/1070a6e3c036f39142c2820c4b52e9243246fcfc3f96239ac84472ba361e/psutil-7.1.0-cp37-abi3-win_arm64.whl", hash = "sha256:6937cb68133e7c97b6cc9649a570c9a18ba0efebed46d8c5dae4c07fa1b67a07", size = 244971, upload-time = "2025-09-17T20:15:12.262Z" }, ] [[package]] @@ -2339,16 +2338,16 @@ wheels = [ [[package]] name = "pycparser" -version = "2.22" +version = "2.23" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736, upload-time = "2024-03-30T13:22:22.564Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2", size = 173734, upload-time = "2025-09-09T13:23:47.91Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552, upload-time = "2024-03-30T13:22:20.476Z" }, + { url = "https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934", size = 118140, upload-time = "2025-09-09T13:23:46.651Z" }, ] [[package]] name = "pydantic" -version = "2.11.7" +version = "2.11.10" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, @@ -2356,9 +2355,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/00/dd/4325abf92c39ba8623b5af936ddb36ffcfe0beae70405d456ab1fb2f5b8c/pydantic-2.11.7.tar.gz", hash = "sha256:d989c3c6cb79469287b1569f7447a17848c998458d49ebe294e975b9baf0f0db", size = 788350, upload-time = "2025-06-14T08:33:17.137Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/54/ecab642b3bed45f7d5f59b38443dcb36ef50f85af192e6ece103dbfe9587/pydantic-2.11.10.tar.gz", hash = "sha256:dc280f0982fbda6c38fada4e476dc0a4f3aeaf9c6ad4c28df68a666ec3c61423", size = 788494, upload-time = "2025-10-04T10:40:41.338Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6a/c0/ec2b1c8712ca690e5d61979dee872603e92b8a32f94cc1b72d53beab008a/pydantic-2.11.7-py3-none-any.whl", hash = "sha256:dde5df002701f6de26248661f6835bbe296a47bf73990135c7d07ce741b9623b", size = 444782, upload-time = "2025-06-14T08:33:14.905Z" }, + { url = "https://files.pythonhosted.org/packages/bd/1f/73c53fcbfb0b5a78f91176df41945ca466e71e9d9d836e5c522abda39ee7/pydantic-2.11.10-py3-none-any.whl", hash = "sha256:802a655709d49bd004c31e865ef37da30b540786a46bfce02333e0e24b5fe29a", size = 444823, upload-time = "2025-10-04T10:40:39.055Z" }, ] [[package]] @@ -2453,29 +2452,29 @@ wheels = [ [[package]] name = "pyparsing" -version = "3.2.3" +version = "3.2.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bb/22/f1129e69d94ffff626bdb5c835506b3a5b4f3d070f17ea295e12c2c6f60f/pyparsing-3.2.3.tar.gz", hash = "sha256:b9c13f1ab8b3b542f72e28f634bad4de758ab3ce4546e4301970ad6fa77c38be", size = 1088608, upload-time = "2025-03-25T05:01:28.114Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/a5/181488fc2b9d093e3972d2a472855aae8a03f000592dbfce716a512b3359/pyparsing-3.2.5.tar.gz", hash = "sha256:2df8d5b7b2802ef88e8d016a2eb9c7aeaa923529cd251ed0fe4608275d4105b6", size = 1099274, upload-time = "2025-09-21T04:11:06.277Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/05/e7/df2285f3d08fee213f2d041540fa4fc9ca6c2d44cf36d3a035bf2a8d2bcc/pyparsing-3.2.3-py3-none-any.whl", hash = "sha256:a749938e02d6fd0b59b356ca504a24982314bb090c383e3cf201c95ef7e2bfcf", size = 111120, upload-time = "2025-03-25T05:01:24.908Z" }, + { url = "https://files.pythonhosted.org/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl", hash = "sha256:e38a4f02064cf41fe6593d328d0512495ad1f3d8a91c4f73fc401b3079a59a5e", size = 113890, upload-time = "2025-09-21T04:11:04.117Z" }, ] [[package]] name = "pyright" -version = "1.1.405" +version = "1.1.406" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "nodeenv" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fb/6c/ba4bbee22e76af700ea593a1d8701e3225080956753bee9750dcc25e2649/pyright-1.1.405.tar.gz", hash = "sha256:5c2a30e1037af27eb463a1cc0b9f6d65fec48478ccf092c1ac28385a15c55763", size = 4068319, upload-time = "2025-09-04T03:37:06.776Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f7/16/6b4fbdd1fef59a0292cbb99f790b44983e390321eccbc5921b4d161da5d1/pyright-1.1.406.tar.gz", hash = "sha256:c4872bc58c9643dac09e8a2e74d472c62036910b3bd37a32813989ef7576ea2c", size = 4113151, upload-time = "2025-10-02T01:04:45.488Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d5/1a/524f832e1ff1962a22a1accc775ca7b143ba2e9f5924bb6749dce566784a/pyright-1.1.405-py3-none-any.whl", hash = "sha256:a2cb13700b5508ce8e5d4546034cb7ea4aedb60215c6c33f56cec7f53996035a", size = 5905038, upload-time = "2025-09-04T03:37:04.913Z" }, + { url = "https://files.pythonhosted.org/packages/f6/a2/e309afbb459f50507103793aaef85ca4348b66814c86bc73908bdeb66d12/pyright-1.1.406-py3-none-any.whl", hash = "sha256:1d81fb43c2407bf566e97e57abb01c811973fdb21b2df8df59f870f688bdca71", size = 5980982, upload-time = "2025-10-02T01:04:43.137Z" }, ] [[package]] name = "pytest" -version = "8.4.1" +version = "8.4.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -2484,35 +2483,48 @@ dependencies = [ { name = "pluggy" }, { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714, upload-time = "2025-06-18T05:48:06.109Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474, upload-time = "2025-06-18T05:48:03.955Z" }, + { url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" }, ] [[package]] name = "pytest-asyncio" -version = "1.1.0" +version = "1.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4e/51/f8794af39eeb870e87a8c8068642fc07bce0c854d6865d7dd0f2a9d338c2/pytest_asyncio-1.1.0.tar.gz", hash = "sha256:796aa822981e01b68c12e4827b8697108f7205020f24b5793b3c41555dab68ea", size = 46652, upload-time = "2025-07-16T04:29:26.393Z" } +sdist = { url = "https://files.pythonhosted.org/packages/42/86/9e3c5f48f7b7b638b216e4b9e645f54d199d7abbbab7a64a13b4e12ba10f/pytest_asyncio-1.2.0.tar.gz", hash = "sha256:c609a64a2a8768462d0c99811ddb8bd2583c33fd33cf7f21af1c142e824ffb57", size = 50119, upload-time = "2025-09-12T07:33:53.816Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/9d/bf86eddabf8c6c9cb1ea9a869d6873b46f105a5d292d3a6f7071f5b07935/pytest_asyncio-1.1.0-py3-none-any.whl", hash = "sha256:5fe2d69607b0bd75c656d1211f969cadba035030156745ee09e7d71740e58ecf", size = 15157, upload-time = "2025-07-16T04:29:24.929Z" }, + { url = "https://files.pythonhosted.org/packages/04/93/2fa34714b7a4ae72f2f8dad66ba17dd9a2c793220719e736dda28b7aec27/pytest_asyncio-1.2.0-py3-none-any.whl", hash = "sha256:8e17ae5e46d8e7efe51ab6494dd2010f4ca8dae51652aa3c8d55acf50bfb2e99", size = 15095, upload-time = "2025-09-12T07:33:52.639Z" }, ] [[package]] name = "pytest-cov" -version = "6.2.1" +version = "7.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "coverage", extra = ["toml"] }, { name = "pluggy" }, { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/18/99/668cade231f434aaa59bbfbf49469068d2ddd945000621d3d165d2e7dd7b/pytest_cov-6.2.1.tar.gz", hash = "sha256:25cc6cc0a5358204b8108ecedc51a9b57b34cc6b8c967cc2c01a4e00d8a67da2", size = 69432, upload-time = "2025-06-12T10:47:47.684Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/f7/c933acc76f5208b3b00089573cf6a2bc26dc80a8aece8f52bb7d6b1855ca/pytest_cov-7.0.0.tar.gz", hash = "sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1", size = 54328, upload-time = "2025-09-09T10:57:02.113Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bc/16/4ea354101abb1287856baa4af2732be351c7bee728065aed451b678153fd/pytest_cov-6.2.1-py3-none-any.whl", hash = "sha256:f5bc4c23f42f1cdd23c70b1dab1bbaef4fc505ba950d53e0081d0730dd7e86d5", size = 24644, upload-time = "2025-06-12T10:47:45.932Z" }, + { url = "https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl", hash = "sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861", size = 22424, upload-time = "2025-09-09T10:57:00.695Z" }, +] + +[[package]] +name = "pytest-timeout" +version = "2.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ac/82/4c9ecabab13363e72d880f2fb504c5f750433b2b6f16e99f4ec21ada284c/pytest_timeout-2.4.0.tar.gz", hash = "sha256:7e68e90b01f9eff71332b25001f85c75495fc4e3a836701876183c4bcfd0540a", size = 17973, upload-time = "2025-05-05T19:44:34.99Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fa/b6/3127540ecdf1464a00e5a01ee60a1b09175f6913f0644ac748494d9c4b21/pytest_timeout-2.4.0-py3-none-any.whl", hash = "sha256:c42667e5cdadb151aeb5b26d114aff6bdf5a907f176a007a30b940d3d865b5c2", size = 14382, upload-time = "2025-05-05T19:44:33.502Z" }, ] [[package]] @@ -2529,11 +2541,11 @@ wheels = [ [[package]] name = "python-json-logger" -version = "3.3.0" +version = "4.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9e/de/d3144a0bceede957f961e975f3752760fbe390d57fbe194baf709d8f1f7b/python_json_logger-3.3.0.tar.gz", hash = "sha256:12b7e74b17775e7d565129296105bbe3910842d9d0eb083fc83a6a617aa8df84", size = 16642, upload-time = "2025-03-07T07:08:27.301Z" } +sdist = { url = "https://files.pythonhosted.org/packages/29/bf/eca6a3d43db1dae7070f70e160ab20b807627ba953663ba07928cdd3dc58/python_json_logger-4.0.0.tar.gz", hash = "sha256:f58e68eb46e1faed27e0f574a55a0455eecd7b8a5b88b85a784519ba3cff047f", size = 17683, upload-time = "2025-10-06T04:15:18.984Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/08/20/0f2523b9e50a8052bc6a8b732dfc8568abbdc42010aef03a2d750bdab3b2/python_json_logger-3.3.0-py3-none-any.whl", hash = "sha256:dd980fae8cffb24c13caf6e158d3d61c0d6d22342f932cb6e9deedab3d35eec7", size = 15163, upload-time = "2025-03-07T07:08:25.627Z" }, + { url = "https://files.pythonhosted.org/packages/51/e5/fecf13f06e5e5f67e8837d777d1bc43fac0ed2b77a676804df5c34744727/python_json_logger-4.0.0-py3-none-any.whl", hash = "sha256:af09c9daf6a813aa4cc7180395f50f2a9e5fa056034c9953aec92e381c5ba1e2", size = 15548, upload-time = "2025-10-06T04:15:17.553Z" }, ] [[package]] @@ -2586,97 +2598,99 @@ wheels = [ [[package]] name = "pywinpty" -version = "3.0.0" +version = "3.0.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/06/df/429cc505dc5f77ab0612c4b60bca2e3dcc81f6c321844ee017d6dc0f4a95/pywinpty-3.0.0.tar.gz", hash = "sha256:68f70e68a9f0766ffdea3fc500351cb7b9b012bcb8239a411f7ff0fc8f86dcb1", size = 28551, upload-time = "2025-08-12T20:33:46.506Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/bb/a7cc2967c5c4eceb6cc49cfe39447d4bfc56e6c865e7c2249b6eb978935f/pywinpty-3.0.2.tar.gz", hash = "sha256:1505cc4cb248af42cb6285a65c9c2086ee9e7e574078ee60933d5d7fa86fb004", size = 30669, upload-time = "2025-10-03T21:16:29.205Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d6/34/30727e8a97709f5033277457df9a293ccddf34d6eb7528e6a1e910265307/pywinpty-3.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:29daa71ac5dcbe1496ef99f4cde85a732b1f0a3b71405d42177dbcf9ee405e5a", size = 2051048, upload-time = "2025-08-12T20:37:18.488Z" }, - { url = "https://files.pythonhosted.org/packages/76/d9/bd2249815c305ef8f879b326db1fe1effc8e5f22bd88e522b4b55231aa6f/pywinpty-3.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:1e0c4b01e5b03b1531d7c5d0e044b8c66dd0288c6d2b661820849f2a8d91aec3", size = 2051564, upload-time = "2025-08-12T20:37:09.128Z" }, - { url = "https://files.pythonhosted.org/packages/e2/77/358b1a97c1d0714f288949372ec64a70884a7eceb3f887042b9ae0bea388/pywinpty-3.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:828cbe756b7e3d25d886fbd5691a1d523cd59c5fb79286bb32bb75c5221e7ba1", size = 2050856, upload-time = "2025-08-12T20:36:09.117Z" }, - { url = "https://files.pythonhosted.org/packages/8f/6c/4249cfb4eb4fdad2c76bc96db0642a40111847c375b92e5b9f4bf289ddd6/pywinpty-3.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:de0cbe27b96e5a2cebd86c4a6b8b4139f978d9c169d44a8edc7e30e88e5d7a69", size = 2050082, upload-time = "2025-08-12T20:36:28.591Z" }, + { url = "https://files.pythonhosted.org/packages/a6/a1/409c1651c9f874d598c10f51ff586c416625601df4bca315d08baec4c3e3/pywinpty-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:327790d70e4c841ebd9d0f295a780177149aeb405bca44c7115a3de5c2054b23", size = 2050304, upload-time = "2025-10-03T21:19:29.466Z" }, + { url = "https://files.pythonhosted.org/packages/02/4e/1098484e042c9485f56f16eb2b69b43b874bd526044ee401512234cf9e04/pywinpty-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:99fdd9b455f0ad6419aba6731a7a0d2f88ced83c3c94a80ff9533d95fa8d8a9e", size = 2050391, upload-time = "2025-10-03T21:19:01.642Z" }, + { url = "https://files.pythonhosted.org/packages/fc/19/b757fe28008236a4a713e813283721b8a40aa60cd7d3f83549f2e25a3155/pywinpty-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:18f78b81e4cfee6aabe7ea8688441d30247b73e52cd9657138015c5f4ee13a51", size = 2050057, upload-time = "2025-10-03T21:19:26.732Z" }, + { url = "https://files.pythonhosted.org/packages/cb/44/cbae12ecf6f4fa4129c36871fd09c6bef4f98d5f625ecefb5e2449765508/pywinpty-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:663383ecfab7fc382cc97ea5c4f7f0bb32c2f889259855df6ea34e5df42d305b", size = 2049874, upload-time = "2025-10-03T21:18:53.923Z" }, ] [[package]] name = "pyyaml" -version = "6.0.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612, upload-time = "2024-08-06T20:32:03.408Z" }, - { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040, upload-time = "2024-08-06T20:32:04.926Z" }, - { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829, upload-time = "2024-08-06T20:32:06.459Z" }, - { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167, upload-time = "2024-08-06T20:32:08.338Z" }, - { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952, upload-time = "2024-08-06T20:32:14.124Z" }, - { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301, upload-time = "2024-08-06T20:32:16.17Z" }, - { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638, upload-time = "2024-08-06T20:32:18.555Z" }, - { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850, upload-time = "2024-08-06T20:32:19.889Z" }, - { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980, upload-time = "2024-08-06T20:32:21.273Z" }, - { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873, upload-time = "2024-08-06T20:32:25.131Z" }, - { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302, upload-time = "2024-08-06T20:32:26.511Z" }, - { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154, upload-time = "2024-08-06T20:32:28.363Z" }, - { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223, upload-time = "2024-08-06T20:32:30.058Z" }, - { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542, upload-time = "2024-08-06T20:32:31.881Z" }, - { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164, upload-time = "2024-08-06T20:32:37.083Z" }, - { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611, upload-time = "2024-08-06T20:32:38.898Z" }, - { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591, upload-time = "2024-08-06T20:32:40.241Z" }, - { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338, upload-time = "2024-08-06T20:32:41.93Z" }, - { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" }, - { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" }, - { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" }, - { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" }, - { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" }, - { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" }, - { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" }, - { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" }, - { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" }, +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, + { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, + { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, + { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, + { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, + { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, + { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, + { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, + { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, ] [[package]] name = "pyzmq" -version = "27.0.2" +version = "27.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "implementation_name == 'pypy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f8/66/159f38d184f08b5f971b467f87b1ab142ab1320d5200825c824b32b84b66/pyzmq-27.0.2.tar.gz", hash = "sha256:b398dd713b18de89730447347e96a0240225e154db56e35b6bb8447ffdb07798", size = 281440, upload-time = "2025-08-21T04:23:26.334Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/42/73/034429ab0f4316bf433eb6c20c3f49d1dc13b2ed4e4d951b283d300a0f35/pyzmq-27.0.2-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:063845960df76599ad4fad69fa4d884b3ba38304272104fdcd7e3af33faeeb1d", size = 1333169, upload-time = "2025-08-21T04:21:12.483Z" }, - { url = "https://files.pythonhosted.org/packages/35/02/c42b3b526eb03a570c889eea85a5602797f800a50ba8b09ddbf7db568b78/pyzmq-27.0.2-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:845a35fb21b88786aeb38af8b271d41ab0967985410f35411a27eebdc578a076", size = 909176, upload-time = "2025-08-21T04:21:13.835Z" }, - { url = "https://files.pythonhosted.org/packages/1b/35/a1c0b988fabbdf2dc5fe94b7c2bcfd61e3533e5109297b8e0daf1d7a8d2d/pyzmq-27.0.2-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:515d20b5c3c86db95503faa989853a8ab692aab1e5336db011cd6d35626c4cb1", size = 668972, upload-time = "2025-08-21T04:21:15.315Z" }, - { url = "https://files.pythonhosted.org/packages/a0/63/908ac865da32ceaeecea72adceadad28ca25b23a2ca5ff018e5bff30116f/pyzmq-27.0.2-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:862aedec0b0684a5050cdb5ec13c2da96d2f8dffda48657ed35e312a4e31553b", size = 856962, upload-time = "2025-08-21T04:21:16.652Z" }, - { url = "https://files.pythonhosted.org/packages/2f/5a/90b3cc20b65cdf9391896fcfc15d8db21182eab810b7ea05a2986912fbe2/pyzmq-27.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2cb5bcfc51c7a4fce335d3bc974fd1d6a916abbcdd2b25f6e89d37b8def25f57", size = 1657712, upload-time = "2025-08-21T04:21:18.666Z" }, - { url = "https://files.pythonhosted.org/packages/c4/3c/32a5a80f9be4759325b8d7b22ce674bb87e586b4c80c6a9d77598b60d6f0/pyzmq-27.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:38ff75b2a36e3a032e9fef29a5871e3e1301a37464e09ba364e3c3193f62982a", size = 2035054, upload-time = "2025-08-21T04:21:20.073Z" }, - { url = "https://files.pythonhosted.org/packages/13/61/71084fe2ff2d7dc5713f8740d735336e87544845dae1207a8e2e16d9af90/pyzmq-27.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7a5709abe8d23ca158a9d0a18c037f4193f5b6afeb53be37173a41e9fb885792", size = 1894010, upload-time = "2025-08-21T04:21:21.96Z" }, - { url = "https://files.pythonhosted.org/packages/cb/6b/77169cfb13b696e50112ca496b2ed23c4b7d8860a1ec0ff3e4b9f9926221/pyzmq-27.0.2-cp311-cp311-win32.whl", hash = "sha256:47c5dda2018c35d87be9b83de0890cb92ac0791fd59498847fc4eca6ff56671d", size = 566819, upload-time = "2025-08-21T04:21:23.31Z" }, - { url = "https://files.pythonhosted.org/packages/37/cd/86c4083e0f811f48f11bc0ddf1e7d13ef37adfd2fd4f78f2445f1cc5dec0/pyzmq-27.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:f54ca3e98f8f4d23e989c7d0edcf9da7a514ff261edaf64d1d8653dd5feb0a8b", size = 633264, upload-time = "2025-08-21T04:21:24.761Z" }, - { url = "https://files.pythonhosted.org/packages/a0/69/5b8bb6a19a36a569fac02153a9e083738785892636270f5f68a915956aea/pyzmq-27.0.2-cp311-cp311-win_arm64.whl", hash = "sha256:2ef3067cb5b51b090fb853f423ad7ed63836ec154374282780a62eb866bf5768", size = 559316, upload-time = "2025-08-21T04:21:26.1Z" }, - { url = "https://files.pythonhosted.org/packages/68/69/b3a729e7b03e412bee2b1823ab8d22e20a92593634f664afd04c6c9d9ac0/pyzmq-27.0.2-cp312-abi3-macosx_10_15_universal2.whl", hash = "sha256:5da05e3c22c95e23bfc4afeee6ff7d4be9ff2233ad6cb171a0e8257cd46b169a", size = 1305910, upload-time = "2025-08-21T04:21:27.609Z" }, - { url = "https://files.pythonhosted.org/packages/15/b7/f6a6a285193d489b223c340b38ee03a673467cb54914da21c3d7849f1b10/pyzmq-27.0.2-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:4e4520577971d01d47e2559bb3175fce1be9103b18621bf0b241abe0a933d040", size = 895507, upload-time = "2025-08-21T04:21:29.005Z" }, - { url = "https://files.pythonhosted.org/packages/17/e6/c4ed2da5ef9182cde1b1f5d0051a986e76339d71720ec1a00be0b49275ad/pyzmq-27.0.2-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:56d7de7bf73165b90bd25a8668659ccb134dd28449116bf3c7e9bab5cf8a8ec9", size = 652670, upload-time = "2025-08-21T04:21:30.71Z" }, - { url = "https://files.pythonhosted.org/packages/0e/66/d781ab0636570d32c745c4e389b1c6b713115905cca69ab6233508622edd/pyzmq-27.0.2-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:340e7cddc32f147c6c00d116a3f284ab07ee63dbd26c52be13b590520434533c", size = 840581, upload-time = "2025-08-21T04:21:32.008Z" }, - { url = "https://files.pythonhosted.org/packages/a6/df/f24790caf565d72544f5c8d8500960b9562c1dc848d6f22f3c7e122e73d4/pyzmq-27.0.2-cp312-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ba95693f9df8bb4a9826464fb0fe89033936f35fd4a8ff1edff09a473570afa0", size = 1641931, upload-time = "2025-08-21T04:21:33.371Z" }, - { url = "https://files.pythonhosted.org/packages/65/65/77d27b19fc5e845367f9100db90b9fce924f611b14770db480615944c9c9/pyzmq-27.0.2-cp312-abi3-musllinux_1_2_i686.whl", hash = "sha256:ca42a6ce2d697537da34f77a1960d21476c6a4af3e539eddb2b114c3cf65a78c", size = 2021226, upload-time = "2025-08-21T04:21:35.301Z" }, - { url = "https://files.pythonhosted.org/packages/5b/65/1ed14421ba27a4207fa694772003a311d1142b7f543179e4d1099b7eb746/pyzmq-27.0.2-cp312-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3e44e665d78a07214b2772ccbd4b9bcc6d848d7895f1b2d7653f047b6318a4f6", size = 1878047, upload-time = "2025-08-21T04:21:36.749Z" }, - { url = "https://files.pythonhosted.org/packages/dd/dc/e578549b89b40dc78a387ec471c2a360766690c0a045cd8d1877d401012d/pyzmq-27.0.2-cp312-abi3-win32.whl", hash = "sha256:272d772d116615397d2be2b1417b3b8c8bc8671f93728c2f2c25002a4530e8f6", size = 558757, upload-time = "2025-08-21T04:21:38.2Z" }, - { url = "https://files.pythonhosted.org/packages/b5/89/06600980aefcc535c758414da969f37a5194ea4cdb73b745223f6af3acfb/pyzmq-27.0.2-cp312-abi3-win_amd64.whl", hash = "sha256:734be4f44efba0aa69bf5f015ed13eb69ff29bf0d17ea1e21588b095a3147b8e", size = 619281, upload-time = "2025-08-21T04:21:39.909Z" }, - { url = "https://files.pythonhosted.org/packages/30/84/df8a5c089552d17c9941d1aea4314b606edf1b1622361dae89aacedc6467/pyzmq-27.0.2-cp312-abi3-win_arm64.whl", hash = "sha256:41f0bd56d9279392810950feb2785a419c2920bbf007fdaaa7f4a07332ae492d", size = 552680, upload-time = "2025-08-21T04:21:41.571Z" }, - { url = "https://files.pythonhosted.org/packages/b4/7b/b79e976508517ab80dc800f7021ef1fb602a6d55e4caa2d47fb3dca5d8b6/pyzmq-27.0.2-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:7f01118133427cd7f34ee133b5098e2af5f70303fa7519785c007bca5aa6f96a", size = 1122259, upload-time = "2025-08-21T04:21:43.063Z" }, - { url = "https://files.pythonhosted.org/packages/2b/1c/777217b9940ebcb7e71c924184ca5f31e410580a58d9fd93798589f0d31c/pyzmq-27.0.2-cp313-cp313-android_24_x86_64.whl", hash = "sha256:e4b860edf6379a7234ccbb19b4ed2c57e3ff569c3414fadfb49ae72b61a8ef07", size = 1156113, upload-time = "2025-08-21T04:21:44.566Z" }, - { url = "https://files.pythonhosted.org/packages/59/7d/654657a4c6435f41538182e71b61eac386a789a2bbb6f30171915253a9a7/pyzmq-27.0.2-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:cb77923ea163156da14295c941930bd525df0d29c96c1ec2fe3c3806b1e17cb3", size = 1341437, upload-time = "2025-08-21T04:21:46.019Z" }, - { url = "https://files.pythonhosted.org/packages/20/a0/5ed7710037f9c096017adc748bcb1698674a2d297f8b9422d38816f7b56a/pyzmq-27.0.2-cp313-cp313t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:61678b7407b04df8f9423f188156355dc94d0fb52d360ae79d02ed7e0d431eea", size = 897888, upload-time = "2025-08-21T04:21:47.362Z" }, - { url = "https://files.pythonhosted.org/packages/2c/8a/6e4699a60931c17e7406641d201d7f2c121e2a38979bc83226a6d8f1ba32/pyzmq-27.0.2-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e3c824b70925963bdc8e39a642672c15ffaa67e7d4b491f64662dd56d6271263", size = 660727, upload-time = "2025-08-21T04:21:48.734Z" }, - { url = "https://files.pythonhosted.org/packages/7b/d8/d761e438c186451bd89ce63a665cde5690c084b61cd8f5d7b51e966e875a/pyzmq-27.0.2-cp313-cp313t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c4833e02fcf2751975457be1dfa2f744d4d09901a8cc106acaa519d868232175", size = 848136, upload-time = "2025-08-21T04:21:50.416Z" }, - { url = "https://files.pythonhosted.org/packages/43/f1/a0f31684efdf3eb92f46b7dd2117e752208115e89d278f8ca5f413c5bb85/pyzmq-27.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b18045668d09cf0faa44918af2a67f0dbbef738c96f61c2f1b975b1ddb92ccfc", size = 1650402, upload-time = "2025-08-21T04:21:52.235Z" }, - { url = "https://files.pythonhosted.org/packages/41/fd/0d7f2a1732812df02c85002770da4a7864c79b210084bcdab01ea57e8d92/pyzmq-27.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:bbbb7e2f3ac5a22901324e7b086f398b8e16d343879a77b15ca3312e8cd8e6d5", size = 2024587, upload-time = "2025-08-21T04:21:54.07Z" }, - { url = "https://files.pythonhosted.org/packages/f1/73/358be69e279a382dd09e46dda29df8446365cddee4f79ef214e71e5b2b5a/pyzmq-27.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:b751914a73604d40d88a061bab042a11d4511b3ddbb7624cd83c39c8a498564c", size = 1885493, upload-time = "2025-08-21T04:21:55.588Z" }, - { url = "https://files.pythonhosted.org/packages/c5/7b/e9951ad53b3dfed8cfb4c2cfd6e0097c9b454e5c0d0e6df5f2b60d7c8c3d/pyzmq-27.0.2-cp313-cp313t-win32.whl", hash = "sha256:3e8f833dd82af11db5321c414638045c70f61009f72dd61c88db4a713c1fb1d2", size = 574934, upload-time = "2025-08-21T04:21:57.52Z" }, - { url = "https://files.pythonhosted.org/packages/55/33/1a7fc3a92f2124a63e6e2a6afa0af471a5c0c713e776b476d4eda5111b13/pyzmq-27.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:5b45153cb8eadcab14139970643a84f7a7b08dda541fbc1f6f4855c49334b549", size = 640932, upload-time = "2025-08-21T04:21:59.527Z" }, - { url = "https://files.pythonhosted.org/packages/2a/52/2598a94ac251a7c83f3887866225eea1952b0d4463a68df5032eb00ff052/pyzmq-27.0.2-cp313-cp313t-win_arm64.whl", hash = "sha256:86898f5c9730df23427c1ee0097d8aa41aa5f89539a79e48cd0d2c22d059f1b7", size = 561315, upload-time = "2025-08-21T04:22:01.295Z" }, - { url = "https://files.pythonhosted.org/packages/c7/60/027d0032a1e3b1aabcef0e309b9ff8a4099bdd5a60ab38b36a676ff2bd7b/pyzmq-27.0.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e297784aea724294fe95e442e39a4376c2f08aa4fae4161c669f047051e31b02", size = 836007, upload-time = "2025-08-21T04:23:00.447Z" }, - { url = "https://files.pythonhosted.org/packages/25/20/2ed1e6168aaea323df9bb2c451309291f53ba3af372ffc16edd4ce15b9e5/pyzmq-27.0.2-pp311-pypy311_pp73-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:e3659a79ded9745bc9c2aef5b444ac8805606e7bc50d2d2eb16dc3ab5483d91f", size = 799932, upload-time = "2025-08-21T04:23:02.052Z" }, - { url = "https://files.pythonhosted.org/packages/fd/25/5c147307de546b502c9373688ce5b25dc22288d23a1ebebe5d587bf77610/pyzmq-27.0.2-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3dba49ff037d02373a9306b58d6c1e0be031438f822044e8767afccfdac4c6b", size = 567459, upload-time = "2025-08-21T04:23:03.593Z" }, - { url = "https://files.pythonhosted.org/packages/71/06/0dc56ffc615c8095cd089c9b98ce5c733e990f09ce4e8eea4aaf1041a532/pyzmq-27.0.2-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de84e1694f9507b29e7b263453a2255a73e3d099d258db0f14539bad258abe41", size = 747088, upload-time = "2025-08-21T04:23:05.334Z" }, - { url = "https://files.pythonhosted.org/packages/06/f6/4a50187e023b8848edd3f0a8e197b1a7fb08d261d8c60aae7cb6c3d71612/pyzmq-27.0.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:f0944d65ba2b872b9fcece08411d6347f15a874c775b4c3baae7f278550da0fb", size = 544639, upload-time = "2025-08-21T04:23:07.279Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/04/0b/3c9baedbdf613ecaa7aa07027780b8867f57b6293b6ee50de316c9f3222b/pyzmq-27.1.0.tar.gz", hash = "sha256:ac0765e3d44455adb6ddbf4417dcce460fc40a05978c08efdf2948072f6db540", size = 281750, upload-time = "2025-09-08T23:10:18.157Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/06/5d/305323ba86b284e6fcb0d842d6adaa2999035f70f8c38a9b6d21ad28c3d4/pyzmq-27.1.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:226b091818d461a3bef763805e75685e478ac17e9008f49fce2d3e52b3d58b86", size = 1333328, upload-time = "2025-09-08T23:07:45.946Z" }, + { url = "https://files.pythonhosted.org/packages/bd/a0/fc7e78a23748ad5443ac3275943457e8452da67fda347e05260261108cbc/pyzmq-27.1.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:0790a0161c281ca9723f804871b4027f2e8b5a528d357c8952d08cd1a9c15581", size = 908803, upload-time = "2025-09-08T23:07:47.551Z" }, + { url = "https://files.pythonhosted.org/packages/7e/22/37d15eb05f3bdfa4abea6f6d96eb3bb58585fbd3e4e0ded4e743bc650c97/pyzmq-27.1.0-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c895a6f35476b0c3a54e3eb6ccf41bf3018de937016e6e18748317f25d4e925f", size = 668836, upload-time = "2025-09-08T23:07:49.436Z" }, + { url = "https://files.pythonhosted.org/packages/b1/c4/2a6fe5111a01005fc7af3878259ce17684fabb8852815eda6225620f3c59/pyzmq-27.1.0-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5bbf8d3630bf96550b3be8e1fc0fea5cbdc8d5466c1192887bd94869da17a63e", size = 857038, upload-time = "2025-09-08T23:07:51.234Z" }, + { url = "https://files.pythonhosted.org/packages/cb/eb/bfdcb41d0db9cd233d6fb22dc131583774135505ada800ebf14dfb0a7c40/pyzmq-27.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:15c8bd0fe0dabf808e2d7a681398c4e5ded70a551ab47482067a572c054c8e2e", size = 1657531, upload-time = "2025-09-08T23:07:52.795Z" }, + { url = "https://files.pythonhosted.org/packages/ab/21/e3180ca269ed4a0de5c34417dfe71a8ae80421198be83ee619a8a485b0c7/pyzmq-27.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:bafcb3dd171b4ae9f19ee6380dfc71ce0390fefaf26b504c0e5f628d7c8c54f2", size = 2034786, upload-time = "2025-09-08T23:07:55.047Z" }, + { url = "https://files.pythonhosted.org/packages/3b/b1/5e21d0b517434b7f33588ff76c177c5a167858cc38ef740608898cd329f2/pyzmq-27.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e829529fcaa09937189178115c49c504e69289abd39967cd8a4c215761373394", size = 1894220, upload-time = "2025-09-08T23:07:57.172Z" }, + { url = "https://files.pythonhosted.org/packages/03/f2/44913a6ff6941905efc24a1acf3d3cb6146b636c546c7406c38c49c403d4/pyzmq-27.1.0-cp311-cp311-win32.whl", hash = "sha256:6df079c47d5902af6db298ec92151db82ecb557af663098b92f2508c398bb54f", size = 567155, upload-time = "2025-09-08T23:07:59.05Z" }, + { url = "https://files.pythonhosted.org/packages/23/6d/d8d92a0eb270a925c9b4dd039c0b4dc10abc2fcbc48331788824ef113935/pyzmq-27.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:190cbf120fbc0fc4957b56866830def56628934a9d112aec0e2507aa6a032b97", size = 633428, upload-time = "2025-09-08T23:08:00.663Z" }, + { url = "https://files.pythonhosted.org/packages/ae/14/01afebc96c5abbbd713ecfc7469cfb1bc801c819a74ed5c9fad9a48801cb/pyzmq-27.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:eca6b47df11a132d1745eb3b5b5e557a7dae2c303277aa0e69c6ba91b8736e07", size = 559497, upload-time = "2025-09-08T23:08:02.15Z" }, + { url = "https://files.pythonhosted.org/packages/92/e7/038aab64a946d535901103da16b953c8c9cc9c961dadcbf3609ed6428d23/pyzmq-27.1.0-cp312-abi3-macosx_10_15_universal2.whl", hash = "sha256:452631b640340c928fa343801b0d07eb0c3789a5ffa843f6e1a9cee0ba4eb4fc", size = 1306279, upload-time = "2025-09-08T23:08:03.807Z" }, + { url = "https://files.pythonhosted.org/packages/e8/5e/c3c49fdd0f535ef45eefcc16934648e9e59dace4a37ee88fc53f6cd8e641/pyzmq-27.1.0-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1c179799b118e554b66da67d88ed66cd37a169f1f23b5d9f0a231b4e8d44a113", size = 895645, upload-time = "2025-09-08T23:08:05.301Z" }, + { url = "https://files.pythonhosted.org/packages/f8/e5/b0b2504cb4e903a74dcf1ebae157f9e20ebb6ea76095f6cfffea28c42ecd/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3837439b7f99e60312f0c926a6ad437b067356dc2bc2ec96eb395fd0fe804233", size = 652574, upload-time = "2025-09-08T23:08:06.828Z" }, + { url = "https://files.pythonhosted.org/packages/f8/9b/c108cdb55560eaf253f0cbdb61b29971e9fb34d9c3499b0e96e4e60ed8a5/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43ad9a73e3da1fab5b0e7e13402f0b2fb934ae1c876c51d0afff0e7c052eca31", size = 840995, upload-time = "2025-09-08T23:08:08.396Z" }, + { url = "https://files.pythonhosted.org/packages/c2/bb/b79798ca177b9eb0825b4c9998c6af8cd2a7f15a6a1a4272c1d1a21d382f/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0de3028d69d4cdc475bfe47a6128eb38d8bc0e8f4d69646adfbcd840facbac28", size = 1642070, upload-time = "2025-09-08T23:08:09.989Z" }, + { url = "https://files.pythonhosted.org/packages/9c/80/2df2e7977c4ede24c79ae39dcef3899bfc5f34d1ca7a5b24f182c9b7a9ca/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_i686.whl", hash = "sha256:cf44a7763aea9298c0aa7dbf859f87ed7012de8bda0f3977b6fb1d96745df856", size = 2021121, upload-time = "2025-09-08T23:08:11.907Z" }, + { url = "https://files.pythonhosted.org/packages/46/bd/2d45ad24f5f5ae7e8d01525eb76786fa7557136555cac7d929880519e33a/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f30f395a9e6fbca195400ce833c731e7b64c3919aa481af4d88c3759e0cb7496", size = 1878550, upload-time = "2025-09-08T23:08:13.513Z" }, + { url = "https://files.pythonhosted.org/packages/e6/2f/104c0a3c778d7c2ab8190e9db4f62f0b6957b53c9d87db77c284b69f33ea/pyzmq-27.1.0-cp312-abi3-win32.whl", hash = "sha256:250e5436a4ba13885494412b3da5d518cd0d3a278a1ae640e113c073a5f88edd", size = 559184, upload-time = "2025-09-08T23:08:15.163Z" }, + { url = "https://files.pythonhosted.org/packages/fc/7f/a21b20d577e4100c6a41795842028235998a643b1ad406a6d4163ea8f53e/pyzmq-27.1.0-cp312-abi3-win_amd64.whl", hash = "sha256:9ce490cf1d2ca2ad84733aa1d69ce6855372cb5ce9223802450c9b2a7cba0ccf", size = 619480, upload-time = "2025-09-08T23:08:17.192Z" }, + { url = "https://files.pythonhosted.org/packages/78/c2/c012beae5f76b72f007a9e91ee9401cb88c51d0f83c6257a03e785c81cc2/pyzmq-27.1.0-cp312-abi3-win_arm64.whl", hash = "sha256:75a2f36223f0d535a0c919e23615fc85a1e23b71f40c7eb43d7b1dedb4d8f15f", size = 552993, upload-time = "2025-09-08T23:08:18.926Z" }, + { url = "https://files.pythonhosted.org/packages/60/cb/84a13459c51da6cec1b7b1dc1a47e6db6da50b77ad7fd9c145842750a011/pyzmq-27.1.0-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:93ad4b0855a664229559e45c8d23797ceac03183c7b6f5b4428152a6b06684a5", size = 1122436, upload-time = "2025-09-08T23:08:20.801Z" }, + { url = "https://files.pythonhosted.org/packages/dc/b6/94414759a69a26c3dd674570a81813c46a078767d931a6c70ad29fc585cb/pyzmq-27.1.0-cp313-cp313-android_24_x86_64.whl", hash = "sha256:fbb4f2400bfda24f12f009cba62ad5734148569ff4949b1b6ec3b519444342e6", size = 1156301, upload-time = "2025-09-08T23:08:22.47Z" }, + { url = "https://files.pythonhosted.org/packages/a5/ad/15906493fd40c316377fd8a8f6b1f93104f97a752667763c9b9c1b71d42d/pyzmq-27.1.0-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:e343d067f7b151cfe4eb3bb796a7752c9d369eed007b91231e817071d2c2fec7", size = 1341197, upload-time = "2025-09-08T23:08:24.286Z" }, + { url = "https://files.pythonhosted.org/packages/14/1d/d343f3ce13db53a54cb8946594e567410b2125394dafcc0268d8dda027e0/pyzmq-27.1.0-cp313-cp313t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:08363b2011dec81c354d694bdecaef4770e0ae96b9afea70b3f47b973655cc05", size = 897275, upload-time = "2025-09-08T23:08:26.063Z" }, + { url = "https://files.pythonhosted.org/packages/69/2d/d83dd6d7ca929a2fc67d2c3005415cdf322af7751d773524809f9e585129/pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d54530c8c8b5b8ddb3318f481297441af102517602b569146185fa10b63f4fa9", size = 660469, upload-time = "2025-09-08T23:08:27.623Z" }, + { url = "https://files.pythonhosted.org/packages/3e/cd/9822a7af117f4bc0f1952dbe9ef8358eb50a24928efd5edf54210b850259/pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6f3afa12c392f0a44a2414056d730eebc33ec0926aae92b5ad5cf26ebb6cc128", size = 847961, upload-time = "2025-09-08T23:08:29.672Z" }, + { url = "https://files.pythonhosted.org/packages/9a/12/f003e824a19ed73be15542f172fd0ec4ad0b60cf37436652c93b9df7c585/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c65047adafe573ff023b3187bb93faa583151627bc9c51fc4fb2c561ed689d39", size = 1650282, upload-time = "2025-09-08T23:08:31.349Z" }, + { url = "https://files.pythonhosted.org/packages/d5/4a/e82d788ed58e9a23995cee70dbc20c9aded3d13a92d30d57ec2291f1e8a3/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:90e6e9441c946a8b0a667356f7078d96411391a3b8f80980315455574177ec97", size = 2024468, upload-time = "2025-09-08T23:08:33.543Z" }, + { url = "https://files.pythonhosted.org/packages/d9/94/2da0a60841f757481e402b34bf4c8bf57fa54a5466b965de791b1e6f747d/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:add071b2d25f84e8189aaf0882d39a285b42fa3853016ebab234a5e78c7a43db", size = 1885394, upload-time = "2025-09-08T23:08:35.51Z" }, + { url = "https://files.pythonhosted.org/packages/4f/6f/55c10e2e49ad52d080dc24e37adb215e5b0d64990b57598abc2e3f01725b/pyzmq-27.1.0-cp313-cp313t-win32.whl", hash = "sha256:7ccc0700cfdf7bd487bea8d850ec38f204478681ea02a582a8da8171b7f90a1c", size = 574964, upload-time = "2025-09-08T23:08:37.178Z" }, + { url = "https://files.pythonhosted.org/packages/87/4d/2534970ba63dd7c522d8ca80fb92777f362c0f321900667c615e2067cb29/pyzmq-27.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:8085a9fba668216b9b4323be338ee5437a235fe275b9d1610e422ccc279733e2", size = 641029, upload-time = "2025-09-08T23:08:40.595Z" }, + { url = "https://files.pythonhosted.org/packages/f6/fa/f8aea7a28b0641f31d40dea42d7ef003fded31e184ef47db696bc74cd610/pyzmq-27.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:6bb54ca21bcfe361e445256c15eedf083f153811c37be87e0514934d6913061e", size = 561541, upload-time = "2025-09-08T23:08:42.668Z" }, + { url = "https://files.pythonhosted.org/packages/4c/c6/c4dcdecdbaa70969ee1fdced6d7b8f60cfabe64d25361f27ac4665a70620/pyzmq-27.1.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:18770c8d3563715387139060d37859c02ce40718d1faf299abddcdcc6a649066", size = 836265, upload-time = "2025-09-08T23:09:49.376Z" }, + { url = "https://files.pythonhosted.org/packages/3e/79/f38c92eeaeb03a2ccc2ba9866f0439593bb08c5e3b714ac1d553e5c96e25/pyzmq-27.1.0-pp311-pypy311_pp73-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:ac25465d42f92e990f8d8b0546b01c391ad431c3bf447683fdc40565941d0604", size = 800208, upload-time = "2025-09-08T23:09:51.073Z" }, + { url = "https://files.pythonhosted.org/packages/49/0e/3f0d0d335c6b3abb9b7b723776d0b21fa7f3a6c819a0db6097059aada160/pyzmq-27.1.0-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:53b40f8ae006f2734ee7608d59ed661419f087521edbfc2149c3932e9c14808c", size = 567747, upload-time = "2025-09-08T23:09:52.698Z" }, + { url = "https://files.pythonhosted.org/packages/a1/cf/f2b3784d536250ffd4be70e049f3b60981235d70c6e8ce7e3ef21e1adb25/pyzmq-27.1.0-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f605d884e7c8be8fe1aa94e0a783bf3f591b84c24e4bc4f3e7564c82ac25e271", size = 747371, upload-time = "2025-09-08T23:09:54.563Z" }, + { url = "https://files.pythonhosted.org/packages/01/1b/5dbe84eefc86f48473947e2f41711aded97eecef1231f4558f1f02713c12/pyzmq-27.1.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c9f7f6e13dff2e44a6afeaf2cf54cee5929ad64afaf4d40b50f93c58fc687355", size = 544862, upload-time = "2025-09-08T23:09:56.509Z" }, ] [[package]] @@ -2859,63 +2873,66 @@ wheels = [ [[package]] name = "ruamel-yaml-clib" -version = "0.2.12" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/20/84/80203abff8ea4993a87d823a5f632e4d92831ef75d404c9fc78d0176d2b5/ruamel.yaml.clib-0.2.12.tar.gz", hash = "sha256:6c8fbb13ec503f99a91901ab46e0b07ae7941cd527393187039aec586fdfd36f", size = 225315, upload-time = "2024-10-20T10:10:56.22Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/fb/8f/683c6ad562f558cbc4f7c029abcd9599148c51c54b5ef0f24f2638da9fbb/ruamel.yaml.clib-0.2.12-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:4a6679521a58256a90b0d89e03992c15144c5f3858f40d7c18886023d7943db6", size = 132224, upload-time = "2024-10-20T10:12:45.162Z" }, - { url = "https://files.pythonhosted.org/packages/3c/d2/b79b7d695e2f21da020bd44c782490578f300dd44f0a4c57a92575758a76/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:d84318609196d6bd6da0edfa25cedfbabd8dbde5140a0a23af29ad4b8f91fb1e", size = 641480, upload-time = "2024-10-20T10:12:46.758Z" }, - { url = "https://files.pythonhosted.org/packages/68/6e/264c50ce2a31473a9fdbf4fa66ca9b2b17c7455b31ef585462343818bd6c/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb43a269eb827806502c7c8efb7ae7e9e9d0573257a46e8e952f4d4caba4f31e", size = 739068, upload-time = "2024-10-20T10:12:48.605Z" }, - { url = "https://files.pythonhosted.org/packages/86/29/88c2567bc893c84d88b4c48027367c3562ae69121d568e8a3f3a8d363f4d/ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:811ea1594b8a0fb466172c384267a4e5e367298af6b228931f273b111f17ef52", size = 703012, upload-time = "2024-10-20T10:12:51.124Z" }, - { url = "https://files.pythonhosted.org/packages/11/46/879763c619b5470820f0cd6ca97d134771e502776bc2b844d2adb6e37753/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cf12567a7b565cbf65d438dec6cfbe2917d3c1bdddfce84a9930b7d35ea59642", size = 704352, upload-time = "2024-10-21T11:26:41.438Z" }, - { url = "https://files.pythonhosted.org/packages/02/80/ece7e6034256a4186bbe50dee28cd032d816974941a6abf6a9d65e4228a7/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7dd5adc8b930b12c8fc5b99e2d535a09889941aa0d0bd06f4749e9a9397c71d2", size = 737344, upload-time = "2024-10-21T11:26:43.62Z" }, - { url = "https://files.pythonhosted.org/packages/f0/ca/e4106ac7e80efbabdf4bf91d3d32fc424e41418458251712f5672eada9ce/ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1492a6051dab8d912fc2adeef0e8c72216b24d57bd896ea607cb90bb0c4981d3", size = 714498, upload-time = "2024-12-11T19:58:15.592Z" }, - { url = "https://files.pythonhosted.org/packages/67/58/b1f60a1d591b771298ffa0428237afb092c7f29ae23bad93420b1eb10703/ruamel.yaml.clib-0.2.12-cp311-cp311-win32.whl", hash = "sha256:bd0a08f0bab19093c54e18a14a10b4322e1eacc5217056f3c063bd2f59853ce4", size = 100205, upload-time = "2024-10-20T10:12:52.865Z" }, - { url = "https://files.pythonhosted.org/packages/b4/4f/b52f634c9548a9291a70dfce26ca7ebce388235c93588a1068028ea23fcc/ruamel.yaml.clib-0.2.12-cp311-cp311-win_amd64.whl", hash = "sha256:a274fb2cb086c7a3dea4322ec27f4cb5cc4b6298adb583ab0e211a4682f241eb", size = 118185, upload-time = "2024-10-20T10:12:54.652Z" }, - { url = "https://files.pythonhosted.org/packages/48/41/e7a405afbdc26af961678474a55373e1b323605a4f5e2ddd4a80ea80f628/ruamel.yaml.clib-0.2.12-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:20b0f8dc160ba83b6dcc0e256846e1a02d044e13f7ea74a3d1d56ede4e48c632", size = 133433, upload-time = "2024-10-20T10:12:55.657Z" }, - { url = "https://files.pythonhosted.org/packages/ec/b0/b850385604334c2ce90e3ee1013bd911aedf058a934905863a6ea95e9eb4/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:943f32bc9dedb3abff9879edc134901df92cfce2c3d5c9348f172f62eb2d771d", size = 647362, upload-time = "2024-10-20T10:12:57.155Z" }, - { url = "https://files.pythonhosted.org/packages/44/d0/3f68a86e006448fb6c005aee66565b9eb89014a70c491d70c08de597f8e4/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95c3829bb364fdb8e0332c9931ecf57d9be3519241323c5274bd82f709cebc0c", size = 754118, upload-time = "2024-10-20T10:12:58.501Z" }, - { url = "https://files.pythonhosted.org/packages/52/a9/d39f3c5ada0a3bb2870d7db41901125dbe2434fa4f12ca8c5b83a42d7c53/ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:749c16fcc4a2b09f28843cda5a193e0283e47454b63ec4b81eaa2242f50e4ccd", size = 706497, upload-time = "2024-10-20T10:13:00.211Z" }, - { url = "https://files.pythonhosted.org/packages/b0/fa/097e38135dadd9ac25aecf2a54be17ddf6e4c23e43d538492a90ab3d71c6/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bf165fef1f223beae7333275156ab2022cffe255dcc51c27f066b4370da81e31", size = 698042, upload-time = "2024-10-21T11:26:46.038Z" }, - { url = "https://files.pythonhosted.org/packages/ec/d5/a659ca6f503b9379b930f13bc6b130c9f176469b73b9834296822a83a132/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:32621c177bbf782ca5a18ba4d7af0f1082a3f6e517ac2a18b3974d4edf349680", size = 745831, upload-time = "2024-10-21T11:26:47.487Z" }, - { url = "https://files.pythonhosted.org/packages/db/5d/36619b61ffa2429eeaefaab4f3374666adf36ad8ac6330d855848d7d36fd/ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b82a7c94a498853aa0b272fd5bc67f29008da798d4f93a2f9f289feb8426a58d", size = 715692, upload-time = "2024-12-11T19:58:17.252Z" }, - { url = "https://files.pythonhosted.org/packages/b1/82/85cb92f15a4231c89b95dfe08b09eb6adca929ef7df7e17ab59902b6f589/ruamel.yaml.clib-0.2.12-cp312-cp312-win32.whl", hash = "sha256:e8c4ebfcfd57177b572e2040777b8abc537cdef58a2120e830124946aa9b42c5", size = 98777, upload-time = "2024-10-20T10:13:01.395Z" }, - { url = "https://files.pythonhosted.org/packages/d7/8f/c3654f6f1ddb75daf3922c3d8fc6005b1ab56671ad56ffb874d908bfa668/ruamel.yaml.clib-0.2.12-cp312-cp312-win_amd64.whl", hash = "sha256:0467c5965282c62203273b838ae77c0d29d7638c8a4e3a1c8bdd3602c10904e4", size = 115523, upload-time = "2024-10-20T10:13:02.768Z" }, - { url = "https://files.pythonhosted.org/packages/29/00/4864119668d71a5fa45678f380b5923ff410701565821925c69780356ffa/ruamel.yaml.clib-0.2.12-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:4c8c5d82f50bb53986a5e02d1b3092b03622c02c2eb78e29bec33fd9593bae1a", size = 132011, upload-time = "2024-10-20T10:13:04.377Z" }, - { url = "https://files.pythonhosted.org/packages/7f/5e/212f473a93ae78c669ffa0cb051e3fee1139cb2d385d2ae1653d64281507/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux2014_aarch64.whl", hash = "sha256:e7e3736715fbf53e9be2a79eb4db68e4ed857017344d697e8b9749444ae57475", size = 642488, upload-time = "2024-10-20T10:13:05.906Z" }, - { url = "https://files.pythonhosted.org/packages/1f/8f/ecfbe2123ade605c49ef769788f79c38ddb1c8fa81e01f4dbf5cf1a44b16/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b7e75b4965e1d4690e93021adfcecccbca7d61c7bddd8e22406ef2ff20d74ef", size = 745066, upload-time = "2024-10-20T10:13:07.26Z" }, - { url = "https://files.pythonhosted.org/packages/e2/a9/28f60726d29dfc01b8decdb385de4ced2ced9faeb37a847bd5cf26836815/ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96777d473c05ee3e5e3c3e999f5d23c6f4ec5b0c38c098b3a5229085f74236c6", size = 701785, upload-time = "2024-10-20T10:13:08.504Z" }, - { url = "https://files.pythonhosted.org/packages/84/7e/8e7ec45920daa7f76046578e4f677a3215fe8f18ee30a9cb7627a19d9b4c/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:3bc2a80e6420ca8b7d3590791e2dfc709c88ab9152c00eeb511c9875ce5778bf", size = 693017, upload-time = "2024-10-21T11:26:48.866Z" }, - { url = "https://files.pythonhosted.org/packages/c5/b3/d650eaade4ca225f02a648321e1ab835b9d361c60d51150bac49063b83fa/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:e188d2699864c11c36cdfdada94d781fd5d6b0071cd9c427bceb08ad3d7c70e1", size = 741270, upload-time = "2024-10-21T11:26:50.213Z" }, - { url = "https://files.pythonhosted.org/packages/87/b8/01c29b924dcbbed75cc45b30c30d565d763b9c4d540545a0eeecffb8f09c/ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4f6f3eac23941b32afccc23081e1f50612bdbe4e982012ef4f5797986828cd01", size = 709059, upload-time = "2024-12-11T19:58:18.846Z" }, - { url = "https://files.pythonhosted.org/packages/30/8c/ed73f047a73638257aa9377ad356bea4d96125b305c34a28766f4445cc0f/ruamel.yaml.clib-0.2.12-cp313-cp313-win32.whl", hash = "sha256:6442cb36270b3afb1b4951f060eccca1ce49f3d087ca1ca4563a6eb479cb3de6", size = 98583, upload-time = "2024-10-20T10:13:09.658Z" }, - { url = "https://files.pythonhosted.org/packages/b0/85/e8e751d8791564dd333d5d9a4eab0a7a115f7e349595417fd50ecae3395c/ruamel.yaml.clib-0.2.12-cp313-cp313-win_amd64.whl", hash = "sha256:e5b8daf27af0b90da7bb903a876477a9e6d7270be6146906b276605997c7e9a3", size = 115190, upload-time = "2024-10-20T10:13:10.66Z" }, +version = "0.2.14" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/e9/39ec4d4b3f91188fad1842748f67d4e749c77c37e353c4e545052ee8e893/ruamel.yaml.clib-0.2.14.tar.gz", hash = "sha256:803f5044b13602d58ea378576dd75aa759f52116a0232608e8fdada4da33752e", size = 225394, upload-time = "2025-09-22T19:51:23.753Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/9f/3c51e9578b8c36fcc4bdd271a1a5bb65963a74a4b6ad1a989768a22f6c2a/ruamel.yaml.clib-0.2.14-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5bae1a073ca4244620425cd3d3aa9746bde590992b98ee8c7c8be8c597ca0d4e", size = 270207, upload-time = "2025-09-23T14:24:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/4a/16/cb02815bc2ae9c66760c0c061d23c7358f9ba51dae95ac85247662b7fbe2/ruamel.yaml.clib-0.2.14-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:0a54e5e40a7a691a426c2703b09b0d61a14294d25cfacc00631aa6f9c964df0d", size = 137780, upload-time = "2025-09-22T19:50:37.734Z" }, + { url = "https://files.pythonhosted.org/packages/31/c6/fc687cd1b93bff8e40861eea46d6dc1a6a778d9a085684e4045ff26a8e40/ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:10d9595b6a19778f3269399eff6bab642608e5966183abc2adbe558a42d4efc9", size = 641590, upload-time = "2025-09-22T19:50:41.978Z" }, + { url = "https://files.pythonhosted.org/packages/45/5d/65a2bc08b709b08576b3f307bf63951ee68a8e047cbbda6f1c9864ecf9a7/ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dba72975485f2b87b786075e18a6e5d07dc2b4d8973beb2732b9b2816f1bad70", size = 738090, upload-time = "2025-09-22T19:50:39.152Z" }, + { url = "https://files.pythonhosted.org/packages/fb/d0/a70a03614d9a6788a3661ab1538879ed2aae4e84d861f101243116308a37/ruamel.yaml.clib-0.2.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:29757bdb7c142f9595cc1b62ec49a3d1c83fab9cef92db52b0ccebaad4eafb98", size = 700744, upload-time = "2025-09-22T19:50:40.811Z" }, + { url = "https://files.pythonhosted.org/packages/77/30/c93fa457611f79946d5cb6cc97493ca5425f3f21891d7b1f9b44eaa1b38e/ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:557df28dbccf79b152fe2d1b935f6063d9cc431199ea2b0e84892f35c03bb0ee", size = 742321, upload-time = "2025-09-23T18:42:48.916Z" }, + { url = "https://files.pythonhosted.org/packages/40/85/e2c54ad637117cd13244a4649946eaa00f32edcb882d1f92df90e079ab00/ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:26a8de280ab0d22b6e3ec745b4a5a07151a0f74aad92dd76ab9c8d8d7087720d", size = 743805, upload-time = "2025-09-22T19:50:43.58Z" }, + { url = "https://files.pythonhosted.org/packages/81/50/f899072c38877d8ef5382e0b3d47f8c4346226c1f52d6945d6f64fec6a2f/ruamel.yaml.clib-0.2.14-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e501c096aa3889133d674605ebd018471bc404a59cbc17da3c5924421c54d97c", size = 769529, upload-time = "2025-09-22T19:50:45.707Z" }, + { url = "https://files.pythonhosted.org/packages/99/7c/96d4b5075e30c65ea2064e40c2d657c7c235d7b6ef18751cf89a935b9041/ruamel.yaml.clib-0.2.14-cp311-cp311-win32.whl", hash = "sha256:915748cfc25b8cfd81b14d00f4bfdb2ab227a30d6d43459034533f4d1c207a2a", size = 100256, upload-time = "2025-09-22T19:50:48.26Z" }, + { url = "https://files.pythonhosted.org/packages/7d/8c/73ee2babd04e8bfcf1fd5c20aa553d18bf0ebc24b592b4f831d12ae46cc0/ruamel.yaml.clib-0.2.14-cp311-cp311-win_amd64.whl", hash = "sha256:4ccba93c1e5a40af45b2f08e4591969fa4697eae951c708f3f83dcbf9f6c6bb1", size = 118234, upload-time = "2025-09-22T19:50:47.019Z" }, + { url = "https://files.pythonhosted.org/packages/b4/42/ccfb34a25289afbbc42017e4d3d4288e61d35b2e00cfc6b92974a6a1f94b/ruamel.yaml.clib-0.2.14-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:6aeadc170090ff1889f0d2c3057557f9cd71f975f17535c26a5d37af98f19c27", size = 271775, upload-time = "2025-09-23T14:24:12.771Z" }, + { url = "https://files.pythonhosted.org/packages/82/73/e628a92e80197ff6a79ab81ec3fa00d4cc082d58ab78d3337b7ba7043301/ruamel.yaml.clib-0.2.14-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:5e56ac47260c0eed992789fa0b8efe43404a9adb608608631a948cee4fc2b052", size = 138842, upload-time = "2025-09-22T19:50:49.156Z" }, + { url = "https://files.pythonhosted.org/packages/2b/c5/346c7094344a60419764b4b1334d9e0285031c961176ff88ffb652405b0c/ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:a911aa73588d9a8b08d662b9484bc0567949529824a55d3885b77e8dd62a127a", size = 647404, upload-time = "2025-09-22T19:50:52.921Z" }, + { url = "https://files.pythonhosted.org/packages/df/99/65080c863eb06d4498de3d6c86f3e90595e02e159fd8529f1565f56cfe2c/ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a05ba88adf3d7189a974b2de7a9d56731548d35dc0a822ec3dc669caa7019b29", size = 753141, upload-time = "2025-09-22T19:50:50.294Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e3/0de85f3e3333f8e29e4b10244374a202a87665d1131798946ee22cf05c7c/ruamel.yaml.clib-0.2.14-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb04c5650de6668b853623eceadcdb1a9f2fee381f5d7b6bc842ee7c239eeec4", size = 703477, upload-time = "2025-09-22T19:50:51.508Z" }, + { url = "https://files.pythonhosted.org/packages/d9/25/0d2f09d8833c7fd77ab8efeff213093c16856479a9d293180a0d89f6bed9/ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:df3ec9959241d07bc261f4983d25a1205ff37703faf42b474f15d54d88b4f8c9", size = 741157, upload-time = "2025-09-23T18:42:50.408Z" }, + { url = "https://files.pythonhosted.org/packages/d3/8c/959f10c2e2153cbdab834c46e6954b6dd9e3b109c8f8c0a3cf1618310985/ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:fbc08c02e9b147a11dfcaa1ac8a83168b699863493e183f7c0c8b12850b7d259", size = 745859, upload-time = "2025-09-22T19:50:54.497Z" }, + { url = "https://files.pythonhosted.org/packages/ed/6b/e580a7c18b485e1a5f30a32cda96b20364b0ba649d9d2baaf72f8bd21f83/ruamel.yaml.clib-0.2.14-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c099cafc1834d3c5dac305865d04235f7c21c167c8dd31ebc3d6bbc357e2f023", size = 770200, upload-time = "2025-09-22T19:50:55.718Z" }, + { url = "https://files.pythonhosted.org/packages/ef/44/3455eebc761dc8e8fdced90f2b0a3fa61e32ba38b50de4130e2d57db0f21/ruamel.yaml.clib-0.2.14-cp312-cp312-win32.whl", hash = "sha256:b5b0f7e294700b615a3bcf6d28b26e6da94e8eba63b079f4ec92e9ba6c0d6b54", size = 98829, upload-time = "2025-09-22T19:50:58.895Z" }, + { url = "https://files.pythonhosted.org/packages/76/ab/5121f7f3b651db93de546f8c982c241397aad0a4765d793aca1dac5eadee/ruamel.yaml.clib-0.2.14-cp312-cp312-win_amd64.whl", hash = "sha256:a37f40a859b503304dd740686359fcf541d6fb3ff7fc10f539af7f7150917c68", size = 115570, upload-time = "2025-09-22T19:50:57.981Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ae/e3811f05415594025e96000349d3400978adaed88d8f98d494352d9761ee/ruamel.yaml.clib-0.2.14-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7e4f9da7e7549946e02a6122dcad00b7c1168513acb1f8a726b1aaf504a99d32", size = 269205, upload-time = "2025-09-23T14:24:15.06Z" }, + { url = "https://files.pythonhosted.org/packages/72/06/7d51f4688d6d72bb72fa74254e1593c4f5ebd0036be5b41fe39315b275e9/ruamel.yaml.clib-0.2.14-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:dd7546c851e59c06197a7c651335755e74aa383a835878ca86d2c650c07a2f85", size = 137417, upload-time = "2025-09-22T19:50:59.82Z" }, + { url = "https://files.pythonhosted.org/packages/5a/08/b4499234a420ef42960eeb05585df5cc7eb25ccb8c980490b079e6367050/ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux2014_aarch64.whl", hash = "sha256:1c1acc3a0209ea9042cc3cfc0790edd2eddd431a2ec3f8283d081e4d5018571e", size = 642558, upload-time = "2025-09-22T19:51:03.388Z" }, + { url = "https://files.pythonhosted.org/packages/b6/ba/1975a27dedf1c4c33306ee67c948121be8710b19387aada29e2f139c43ee/ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2070bf0ad1540d5c77a664de07ebcc45eebd1ddcab71a7a06f26936920692beb", size = 744087, upload-time = "2025-09-22T19:51:00.897Z" }, + { url = "https://files.pythonhosted.org/packages/20/15/8a19a13d27f3bd09fa18813add8380a29115a47b553845f08802959acbce/ruamel.yaml.clib-0.2.14-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd8fe07f49c170e09d76773fb86ad9135e0beee44f36e1576a201b0676d3d1d", size = 699709, upload-time = "2025-09-22T19:51:02.075Z" }, + { url = "https://files.pythonhosted.org/packages/19/ee/8d6146a079ad21e534b5083c9ee4a4c8bec42f79cf87594b60978286b39a/ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ff86876889ea478b1381089e55cf9e345707b312beda4986f823e1d95e8c0f59", size = 708926, upload-time = "2025-09-23T18:42:51.707Z" }, + { url = "https://files.pythonhosted.org/packages/a9/f5/426b714abdc222392e68f3b8ad323930d05a214a27c7e7a0f06c69126401/ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1f118b707eece8cf84ecbc3e3ec94d9db879d85ed608f95870d39b2d2efa5dca", size = 740202, upload-time = "2025-09-22T19:51:04.673Z" }, + { url = "https://files.pythonhosted.org/packages/3d/ac/3c5c2b27a183f4fda8a57c82211721c016bcb689a4a175865f7646db9f94/ruamel.yaml.clib-0.2.14-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b30110b29484adc597df6bd92a37b90e63a8c152ca8136aad100a02f8ba6d1b6", size = 765196, upload-time = "2025-09-22T19:51:05.916Z" }, + { url = "https://files.pythonhosted.org/packages/92/2e/06f56a71fd55021c993ed6e848c9b2e5e9cfce180a42179f0ddd28253f7c/ruamel.yaml.clib-0.2.14-cp313-cp313-win32.whl", hash = "sha256:f4e97a1cf0b7a30af9e1d9dad10a5671157b9acee790d9e26996391f49b965a2", size = 98635, upload-time = "2025-09-22T19:51:08.183Z" }, + { url = "https://files.pythonhosted.org/packages/51/79/76aba16a1689b50528224b182f71097ece338e7a4ab55e84c2e73443b78a/ruamel.yaml.clib-0.2.14-cp313-cp313-win_amd64.whl", hash = "sha256:090782b5fb9d98df96509eecdbcaffd037d47389a89492320280d52f91330d78", size = 115238, upload-time = "2025-09-22T19:51:07.081Z" }, ] [[package]] name = "ruff" -version = "0.12.11" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/de/55/16ab6a7d88d93001e1ae4c34cbdcfb376652d761799459ff27c1dc20f6fa/ruff-0.12.11.tar.gz", hash = "sha256:c6b09ae8426a65bbee5425b9d0b82796dbb07cb1af045743c79bfb163001165d", size = 5347103, upload-time = "2025-08-28T13:59:08.87Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d6/a2/3b3573e474de39a7a475f3fbaf36a25600bfeb238e1a90392799163b64a0/ruff-0.12.11-py3-none-linux_armv6l.whl", hash = "sha256:93fce71e1cac3a8bf9200e63a38ac5c078f3b6baebffb74ba5274fb2ab276065", size = 11979885, upload-time = "2025-08-28T13:58:26.654Z" }, - { url = "https://files.pythonhosted.org/packages/76/e4/235ad6d1785a2012d3ded2350fd9bc5c5af8c6f56820e696b0118dfe7d24/ruff-0.12.11-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b8e33ac7b28c772440afa80cebb972ffd823621ded90404f29e5ab6d1e2d4b93", size = 12742364, upload-time = "2025-08-28T13:58:30.256Z" }, - { url = "https://files.pythonhosted.org/packages/2c/0d/15b72c5fe6b1e402a543aa9d8960e0a7e19dfb079f5b0b424db48b7febab/ruff-0.12.11-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d69fb9d4937aa19adb2e9f058bc4fbfe986c2040acb1a4a9747734834eaa0bfd", size = 11920111, upload-time = "2025-08-28T13:58:33.677Z" }, - { url = "https://files.pythonhosted.org/packages/3e/c0/f66339d7893798ad3e17fa5a1e587d6fd9806f7c1c062b63f8b09dda6702/ruff-0.12.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:411954eca8464595077a93e580e2918d0a01a19317af0a72132283e28ae21bee", size = 12160060, upload-time = "2025-08-28T13:58:35.74Z" }, - { url = "https://files.pythonhosted.org/packages/03/69/9870368326db26f20c946205fb2d0008988aea552dbaec35fbacbb46efaa/ruff-0.12.11-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6a2c0a2e1a450f387bf2c6237c727dd22191ae8c00e448e0672d624b2bbd7fb0", size = 11799848, upload-time = "2025-08-28T13:58:38.051Z" }, - { url = "https://files.pythonhosted.org/packages/25/8c/dd2c7f990e9b3a8a55eee09d4e675027d31727ce33cdb29eab32d025bdc9/ruff-0.12.11-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ca4c3a7f937725fd2413c0e884b5248a19369ab9bdd850b5781348ba283f644", size = 13536288, upload-time = "2025-08-28T13:58:40.046Z" }, - { url = "https://files.pythonhosted.org/packages/7a/30/d5496fa09aba59b5e01ea76775a4c8897b13055884f56f1c35a4194c2297/ruff-0.12.11-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:4d1df0098124006f6a66ecf3581a7f7e754c4df7644b2e6704cd7ca80ff95211", size = 14490633, upload-time = "2025-08-28T13:58:42.285Z" }, - { url = "https://files.pythonhosted.org/packages/9b/2f/81f998180ad53445d403c386549d6946d0748e536d58fce5b5e173511183/ruff-0.12.11-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5a8dd5f230efc99a24ace3b77e3555d3fbc0343aeed3fc84c8d89e75ab2ff793", size = 13888430, upload-time = "2025-08-28T13:58:44.641Z" }, - { url = "https://files.pythonhosted.org/packages/87/71/23a0d1d5892a377478c61dbbcffe82a3476b050f38b5162171942a029ef3/ruff-0.12.11-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4dc75533039d0ed04cd33fb8ca9ac9620b99672fe7ff1533b6402206901c34ee", size = 12913133, upload-time = "2025-08-28T13:58:47.039Z" }, - { url = "https://files.pythonhosted.org/packages/80/22/3c6cef96627f89b344c933781ed38329bfb87737aa438f15da95907cbfd5/ruff-0.12.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4fc58f9266d62c6eccc75261a665f26b4ef64840887fc6cbc552ce5b29f96cc8", size = 13169082, upload-time = "2025-08-28T13:58:49.157Z" }, - { url = "https://files.pythonhosted.org/packages/05/b5/68b3ff96160d8b49e8dd10785ff3186be18fd650d356036a3770386e6c7f/ruff-0.12.11-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:5a0113bd6eafd545146440225fe60b4e9489f59eb5f5f107acd715ba5f0b3d2f", size = 13139490, upload-time = "2025-08-28T13:58:51.593Z" }, - { url = "https://files.pythonhosted.org/packages/59/b9/050a3278ecd558f74f7ee016fbdf10591d50119df8d5f5da45a22c6afafc/ruff-0.12.11-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:0d737b4059d66295c3ea5720e6efc152623bb83fde5444209b69cd33a53e2000", size = 11958928, upload-time = "2025-08-28T13:58:53.943Z" }, - { url = "https://files.pythonhosted.org/packages/f9/bc/93be37347db854806904a43b0493af8d6873472dfb4b4b8cbb27786eb651/ruff-0.12.11-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:916fc5defee32dbc1fc1650b576a8fed68f5e8256e2180d4d9855aea43d6aab2", size = 11764513, upload-time = "2025-08-28T13:58:55.976Z" }, - { url = "https://files.pythonhosted.org/packages/7a/a1/1471751e2015a81fd8e166cd311456c11df74c7e8769d4aabfbc7584c7ac/ruff-0.12.11-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c984f07d7adb42d3ded5be894fb4007f30f82c87559438b4879fe7aa08c62b39", size = 12745154, upload-time = "2025-08-28T13:58:58.16Z" }, - { url = "https://files.pythonhosted.org/packages/68/ab/2542b14890d0f4872dd81b7b2a6aed3ac1786fae1ce9b17e11e6df9e31e3/ruff-0.12.11-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e07fbb89f2e9249f219d88331c833860489b49cdf4b032b8e4432e9b13e8a4b9", size = 13227653, upload-time = "2025-08-28T13:59:00.276Z" }, - { url = "https://files.pythonhosted.org/packages/22/16/2fbfc61047dbfd009c58a28369a693a1484ad15441723be1cd7fe69bb679/ruff-0.12.11-py3-none-win32.whl", hash = "sha256:c792e8f597c9c756e9bcd4d87cf407a00b60af77078c96f7b6366ea2ce9ba9d3", size = 11944270, upload-time = "2025-08-28T13:59:02.347Z" }, - { url = "https://files.pythonhosted.org/packages/08/a5/34276984705bfe069cd383101c45077ee029c3fe3b28225bf67aa35f0647/ruff-0.12.11-py3-none-win_amd64.whl", hash = "sha256:a3283325960307915b6deb3576b96919ee89432ebd9c48771ca12ee8afe4a0fd", size = 13046600, upload-time = "2025-08-28T13:59:04.751Z" }, - { url = "https://files.pythonhosted.org/packages/84/a8/001d4a7c2b37623a3fd7463208267fb906df40ff31db496157549cfd6e72/ruff-0.12.11-py3-none-win_arm64.whl", hash = "sha256:bae4d6e6a2676f8fb0f98b74594a048bae1b944aab17e9f5d504062303c6dbea", size = 12135290, upload-time = "2025-08-28T13:59:06.933Z" }, +version = "0.13.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/8e/f9f9ca747fea8e3ac954e3690d4698c9737c23b51731d02df999c150b1c9/ruff-0.13.3.tar.gz", hash = "sha256:5b0ba0db740eefdfbcce4299f49e9eaefc643d4d007749d77d047c2bab19908e", size = 5438533, upload-time = "2025-10-02T19:29:31.582Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/33/8f7163553481466a92656d35dea9331095122bb84cf98210bef597dd2ecd/ruff-0.13.3-py3-none-linux_armv6l.whl", hash = "sha256:311860a4c5e19189c89d035638f500c1e191d283d0cc2f1600c8c80d6dcd430c", size = 12484040, upload-time = "2025-10-02T19:28:49.199Z" }, + { url = "https://files.pythonhosted.org/packages/b0/b5/4a21a4922e5dd6845e91896b0d9ef493574cbe061ef7d00a73c61db531af/ruff-0.13.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:2bdad6512fb666b40fcadb65e33add2b040fc18a24997d2e47fee7d66f7fcae2", size = 13122975, upload-time = "2025-10-02T19:28:52.446Z" }, + { url = "https://files.pythonhosted.org/packages/40/90/15649af836d88c9f154e5be87e64ae7d2b1baa5a3ef317cb0c8fafcd882d/ruff-0.13.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:fc6fa4637284708d6ed4e5e970d52fc3b76a557d7b4e85a53013d9d201d93286", size = 12346621, upload-time = "2025-10-02T19:28:54.712Z" }, + { url = "https://files.pythonhosted.org/packages/a5/42/bcbccb8141305f9a6d3f72549dd82d1134299177cc7eaf832599700f95a7/ruff-0.13.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c9e6469864f94a98f412f20ea143d547e4c652f45e44f369d7b74ee78185838", size = 12574408, upload-time = "2025-10-02T19:28:56.679Z" }, + { url = "https://files.pythonhosted.org/packages/ce/19/0f3681c941cdcfa2d110ce4515624c07a964dc315d3100d889fcad3bfc9e/ruff-0.13.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5bf62b705f319476c78891e0e97e965b21db468b3c999086de8ffb0d40fd2822", size = 12285330, upload-time = "2025-10-02T19:28:58.79Z" }, + { url = "https://files.pythonhosted.org/packages/10/f8/387976bf00d126b907bbd7725219257feea58650e6b055b29b224d8cb731/ruff-0.13.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78cc1abed87ce40cb07ee0667ce99dbc766c9f519eabfd948ed87295d8737c60", size = 13980815, upload-time = "2025-10-02T19:29:01.577Z" }, + { url = "https://files.pythonhosted.org/packages/0c/a6/7c8ec09d62d5a406e2b17d159e4817b63c945a8b9188a771193b7e1cc0b5/ruff-0.13.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:4fb75e7c402d504f7a9a259e0442b96403fa4a7310ffe3588d11d7e170d2b1e3", size = 14987733, upload-time = "2025-10-02T19:29:04.036Z" }, + { url = "https://files.pythonhosted.org/packages/97/e5/f403a60a12258e0fd0c2195341cfa170726f254c788673495d86ab5a9a9d/ruff-0.13.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:17b951f9d9afb39330b2bdd2dd144ce1c1335881c277837ac1b50bfd99985ed3", size = 14439848, upload-time = "2025-10-02T19:29:06.684Z" }, + { url = "https://files.pythonhosted.org/packages/39/49/3de381343e89364c2334c9f3268b0349dc734fc18b2d99a302d0935c8345/ruff-0.13.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6052f8088728898e0a449f0dde8fafc7ed47e4d878168b211977e3e7e854f662", size = 13421890, upload-time = "2025-10-02T19:29:08.767Z" }, + { url = "https://files.pythonhosted.org/packages/ab/b5/c0feca27d45ae74185a6bacc399f5d8920ab82df2d732a17213fb86a2c4c/ruff-0.13.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc742c50f4ba72ce2a3be362bd359aef7d0d302bf7637a6f942eaa763bd292af", size = 13444870, upload-time = "2025-10-02T19:29:11.234Z" }, + { url = "https://files.pythonhosted.org/packages/50/a1/b655298a1f3fda4fdc7340c3f671a4b260b009068fbeb3e4e151e9e3e1bf/ruff-0.13.3-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:8e5640349493b378431637019366bbd73c927e515c9c1babfea3e932f5e68e1d", size = 13691599, upload-time = "2025-10-02T19:29:13.353Z" }, + { url = "https://files.pythonhosted.org/packages/32/b0/a8705065b2dafae007bcae21354e6e2e832e03eb077bb6c8e523c2becb92/ruff-0.13.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6b139f638a80eae7073c691a5dd8d581e0ba319540be97c343d60fb12949c8d0", size = 12421893, upload-time = "2025-10-02T19:29:15.668Z" }, + { url = "https://files.pythonhosted.org/packages/0d/1e/cbe7082588d025cddbb2f23e6dfef08b1a2ef6d6f8328584ad3015b5cebd/ruff-0.13.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:6b547def0a40054825de7cfa341039ebdfa51f3d4bfa6a0772940ed351d2746c", size = 12267220, upload-time = "2025-10-02T19:29:17.583Z" }, + { url = "https://files.pythonhosted.org/packages/a5/99/4086f9c43f85e0755996d09bdcb334b6fee9b1eabdf34e7d8b877fadf964/ruff-0.13.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9cc48a3564423915c93573f1981d57d101e617839bef38504f85f3677b3a0a3e", size = 13177818, upload-time = "2025-10-02T19:29:19.943Z" }, + { url = "https://files.pythonhosted.org/packages/9b/de/7b5db7e39947d9dc1c5f9f17b838ad6e680527d45288eeb568e860467010/ruff-0.13.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1a993b17ec03719c502881cb2d5f91771e8742f2ca6de740034433a97c561989", size = 13618715, upload-time = "2025-10-02T19:29:22.527Z" }, + { url = "https://files.pythonhosted.org/packages/28/d3/bb25ee567ce2f61ac52430cf99f446b0e6d49bdfa4188699ad005fdd16aa/ruff-0.13.3-py3-none-win32.whl", hash = "sha256:f14e0d1fe6460f07814d03c6e32e815bff411505178a1f539a38f6097d3e8ee3", size = 12334488, upload-time = "2025-10-02T19:29:24.782Z" }, + { url = "https://files.pythonhosted.org/packages/cf/49/12f5955818a1139eed288753479ba9d996f6ea0b101784bb1fe6977ec128/ruff-0.13.3-py3-none-win_amd64.whl", hash = "sha256:621e2e5812b691d4f244638d693e640f188bacbb9bc793ddd46837cea0503dd2", size = 13455262, upload-time = "2025-10-02T19:29:26.882Z" }, + { url = "https://files.pythonhosted.org/packages/fe/72/7b83242b26627a00e3af70d0394d68f8f02750d642567af12983031777fc/ruff-0.13.3-py3-none-win_arm64.whl", hash = "sha256:9e9e9d699841eaf4c2c798fa783df2fabc680b72059a02ca0ed81c460bc58330", size = 12538484, upload-time = "2025-10-02T19:29:28.951Z" }, ] [[package]] @@ -2952,7 +2969,7 @@ wheels = [ [[package]] name = "scikit-learn" -version = "1.7.1" +version = "1.7.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "joblib" }, @@ -2960,87 +2977,91 @@ dependencies = [ { name = "scipy" }, { name = "threadpoolctl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/41/84/5f4af978fff619706b8961accac84780a6d298d82a8873446f72edb4ead0/scikit_learn-1.7.1.tar.gz", hash = "sha256:24b3f1e976a4665aa74ee0fcaac2b8fccc6ae77c8e07ab25da3ba6d3292b9802", size = 7190445, upload-time = "2025-07-18T08:01:54.5Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b4/bd/a23177930abd81b96daffa30ef9c54ddbf544d3226b8788ce4c3ef1067b4/scikit_learn-1.7.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:90c8494ea23e24c0fb371afc474618c1019dc152ce4a10e4607e62196113851b", size = 9334838, upload-time = "2025-07-18T08:01:11.239Z" }, - { url = "https://files.pythonhosted.org/packages/8d/a1/d3a7628630a711e2ac0d1a482910da174b629f44e7dd8cfcd6924a4ef81a/scikit_learn-1.7.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:bb870c0daf3bf3be145ec51df8ac84720d9972170786601039f024bf6d61a518", size = 8651241, upload-time = "2025-07-18T08:01:13.234Z" }, - { url = "https://files.pythonhosted.org/packages/26/92/85ec172418f39474c1cd0221d611345d4f433fc4ee2fc68e01f524ccc4e4/scikit_learn-1.7.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:40daccd1b5623f39e8943ab39735cadf0bdce80e67cdca2adcb5426e987320a8", size = 9718677, upload-time = "2025-07-18T08:01:15.649Z" }, - { url = "https://files.pythonhosted.org/packages/df/ce/abdb1dcbb1d2b66168ec43b23ee0cee356b4cc4100ddee3943934ebf1480/scikit_learn-1.7.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:30d1f413cfc0aa5a99132a554f1d80517563c34a9d3e7c118fde2d273c6fe0f7", size = 9511189, upload-time = "2025-07-18T08:01:18.013Z" }, - { url = "https://files.pythonhosted.org/packages/b2/3b/47b5eaee01ef2b5a80ba3f7f6ecf79587cb458690857d4777bfd77371c6f/scikit_learn-1.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:c711d652829a1805a95d7fe96654604a8f16eab5a9e9ad87b3e60173415cb650", size = 8914794, upload-time = "2025-07-18T08:01:20.357Z" }, - { url = "https://files.pythonhosted.org/packages/cb/16/57f176585b35ed865f51b04117947fe20f130f78940c6477b6d66279c9c2/scikit_learn-1.7.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3cee419b49b5bbae8796ecd690f97aa412ef1674410c23fc3257c6b8b85b8087", size = 9260431, upload-time = "2025-07-18T08:01:22.77Z" }, - { url = "https://files.pythonhosted.org/packages/67/4e/899317092f5efcab0e9bc929e3391341cec8fb0e816c4789686770024580/scikit_learn-1.7.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:2fd8b8d35817b0d9ebf0b576f7d5ffbbabdb55536b0655a8aaae629d7ffd2e1f", size = 8637191, upload-time = "2025-07-18T08:01:24.731Z" }, - { url = "https://files.pythonhosted.org/packages/f3/1b/998312db6d361ded1dd56b457ada371a8d8d77ca2195a7d18fd8a1736f21/scikit_learn-1.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:588410fa19a96a69763202f1d6b7b91d5d7a5d73be36e189bc6396bfb355bd87", size = 9486346, upload-time = "2025-07-18T08:01:26.713Z" }, - { url = "https://files.pythonhosted.org/packages/ad/09/a2aa0b4e644e5c4ede7006748f24e72863ba2ae71897fecfd832afea01b4/scikit_learn-1.7.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e3142f0abe1ad1d1c31a2ae987621e41f6b578144a911ff4ac94781a583adad7", size = 9290988, upload-time = "2025-07-18T08:01:28.938Z" }, - { url = "https://files.pythonhosted.org/packages/15/fa/c61a787e35f05f17fc10523f567677ec4eeee5f95aa4798dbbbcd9625617/scikit_learn-1.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:3ddd9092c1bd469acab337d87930067c87eac6bd544f8d5027430983f1e1ae88", size = 8735568, upload-time = "2025-07-18T08:01:30.936Z" }, - { url = "https://files.pythonhosted.org/packages/52/f8/e0533303f318a0f37b88300d21f79b6ac067188d4824f1047a37214ab718/scikit_learn-1.7.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b7839687fa46d02e01035ad775982f2470be2668e13ddd151f0f55a5bf123bae", size = 9213143, upload-time = "2025-07-18T08:01:32.942Z" }, - { url = "https://files.pythonhosted.org/packages/71/f3/f1df377d1bdfc3e3e2adc9c119c238b182293e6740df4cbeac6de2cc3e23/scikit_learn-1.7.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:a10f276639195a96c86aa572ee0698ad64ee939a7b042060b98bd1930c261d10", size = 8591977, upload-time = "2025-07-18T08:01:34.967Z" }, - { url = "https://files.pythonhosted.org/packages/99/72/c86a4cd867816350fe8dee13f30222340b9cd6b96173955819a5561810c5/scikit_learn-1.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:13679981fdaebc10cc4c13c43344416a86fcbc61449cb3e6517e1df9d12c8309", size = 9436142, upload-time = "2025-07-18T08:01:37.397Z" }, - { url = "https://files.pythonhosted.org/packages/e8/66/277967b29bd297538dc7a6ecfb1a7dce751beabd0d7f7a2233be7a4f7832/scikit_learn-1.7.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4f1262883c6a63f067a980a8cdd2d2e7f2513dddcef6a9eaada6416a7a7cbe43", size = 9282996, upload-time = "2025-07-18T08:01:39.721Z" }, - { url = "https://files.pythonhosted.org/packages/e2/47/9291cfa1db1dae9880420d1e07dbc7e8dd4a7cdbc42eaba22512e6bde958/scikit_learn-1.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:ca6d31fb10e04d50bfd2b50d66744729dbb512d4efd0223b864e2fdbfc4cee11", size = 8707418, upload-time = "2025-07-18T08:01:42.124Z" }, - { url = "https://files.pythonhosted.org/packages/61/95/45726819beccdaa34d3362ea9b2ff9f2b5d3b8bf721bd632675870308ceb/scikit_learn-1.7.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:781674d096303cfe3d351ae6963ff7c958db61cde3421cd490e3a5a58f2a94ae", size = 9561466, upload-time = "2025-07-18T08:01:44.195Z" }, - { url = "https://files.pythonhosted.org/packages/ee/1c/6f4b3344805de783d20a51eb24d4c9ad4b11a7f75c1801e6ec6d777361fd/scikit_learn-1.7.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:10679f7f125fe7ecd5fad37dd1aa2daae7e3ad8df7f3eefa08901b8254b3e12c", size = 9040467, upload-time = "2025-07-18T08:01:46.671Z" }, - { url = "https://files.pythonhosted.org/packages/6f/80/abe18fe471af9f1d181904203d62697998b27d9b62124cd281d740ded2f9/scikit_learn-1.7.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1f812729e38c8cb37f760dce71a9b83ccfb04f59b3dca7c6079dcdc60544fa9e", size = 9532052, upload-time = "2025-07-18T08:01:48.676Z" }, - { url = "https://files.pythonhosted.org/packages/14/82/b21aa1e0c4cee7e74864d3a5a721ab8fcae5ca55033cb6263dca297ed35b/scikit_learn-1.7.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:88e1a20131cf741b84b89567e1717f27a2ced228e0f29103426102bc2e3b8ef7", size = 9361575, upload-time = "2025-07-18T08:01:50.639Z" }, - { url = "https://files.pythonhosted.org/packages/f2/20/f4777fcd5627dc6695fa6b92179d0edb7a3ac1b91bcd9a1c7f64fa7ade23/scikit_learn-1.7.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b1bd1d919210b6a10b7554b717c9000b5485aa95a1d0f177ae0d7ee8ec750da5", size = 9277310, upload-time = "2025-07-18T08:01:52.547Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/98/c2/a7855e41c9d285dfe86dc50b250978105dce513d6e459ea66a6aeb0e1e0c/scikit_learn-1.7.2.tar.gz", hash = "sha256:20e9e49ecd130598f1ca38a1d85090e1a600147b9c02fa6f15d69cb53d968fda", size = 7193136, upload-time = "2025-09-09T08:21:29.075Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/83/564e141eef908a5863a54da8ca342a137f45a0bfb71d1d79704c9894c9d1/scikit_learn-1.7.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7509693451651cd7361d30ce4e86a1347493554f172b1c72a39300fa2aea79e", size = 9331967, upload-time = "2025-09-09T08:20:32.421Z" }, + { url = "https://files.pythonhosted.org/packages/18/d6/ba863a4171ac9d7314c4d3fc251f015704a2caeee41ced89f321c049ed83/scikit_learn-1.7.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:0486c8f827c2e7b64837c731c8feff72c0bd2b998067a8a9cbc10643c31f0fe1", size = 8648645, upload-time = "2025-09-09T08:20:34.436Z" }, + { url = "https://files.pythonhosted.org/packages/ef/0e/97dbca66347b8cf0ea8b529e6bb9367e337ba2e8be0ef5c1a545232abfde/scikit_learn-1.7.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:89877e19a80c7b11a2891a27c21c4894fb18e2c2e077815bcade10d34287b20d", size = 9715424, upload-time = "2025-09-09T08:20:36.776Z" }, + { url = "https://files.pythonhosted.org/packages/f7/32/1f3b22e3207e1d2c883a7e09abb956362e7d1bd2f14458c7de258a26ac15/scikit_learn-1.7.2-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8da8bf89d4d79aaec192d2bda62f9b56ae4e5b4ef93b6a56b5de4977e375c1f1", size = 9509234, upload-time = "2025-09-09T08:20:38.957Z" }, + { url = "https://files.pythonhosted.org/packages/9f/71/34ddbd21f1da67c7a768146968b4d0220ee6831e4bcbad3e03dd3eae88b6/scikit_learn-1.7.2-cp311-cp311-win_amd64.whl", hash = "sha256:9b7ed8d58725030568523e937c43e56bc01cadb478fc43c042a9aca1dacb3ba1", size = 8894244, upload-time = "2025-09-09T08:20:41.166Z" }, + { url = "https://files.pythonhosted.org/packages/a7/aa/3996e2196075689afb9fce0410ebdb4a09099d7964d061d7213700204409/scikit_learn-1.7.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:8d91a97fa2b706943822398ab943cde71858a50245e31bc71dba62aab1d60a96", size = 9259818, upload-time = "2025-09-09T08:20:43.19Z" }, + { url = "https://files.pythonhosted.org/packages/43/5d/779320063e88af9c4a7c2cf463ff11c21ac9c8bd730c4a294b0000b666c9/scikit_learn-1.7.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:acbc0f5fd2edd3432a22c69bed78e837c70cf896cd7993d71d51ba6708507476", size = 8636997, upload-time = "2025-09-09T08:20:45.468Z" }, + { url = "https://files.pythonhosted.org/packages/5c/d0/0c577d9325b05594fdd33aa970bf53fb673f051a45496842caee13cfd7fe/scikit_learn-1.7.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e5bf3d930aee75a65478df91ac1225ff89cd28e9ac7bd1196853a9229b6adb0b", size = 9478381, upload-time = "2025-09-09T08:20:47.982Z" }, + { url = "https://files.pythonhosted.org/packages/82/70/8bf44b933837ba8494ca0fc9a9ab60f1c13b062ad0197f60a56e2fc4c43e/scikit_learn-1.7.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4d6e9deed1a47aca9fe2f267ab8e8fe82ee20b4526b2c0cd9e135cea10feb44", size = 9300296, upload-time = "2025-09-09T08:20:50.366Z" }, + { url = "https://files.pythonhosted.org/packages/c6/99/ed35197a158f1fdc2fe7c3680e9c70d0128f662e1fee4ed495f4b5e13db0/scikit_learn-1.7.2-cp312-cp312-win_amd64.whl", hash = "sha256:6088aa475f0785e01bcf8529f55280a3d7d298679f50c0bb70a2364a82d0b290", size = 8731256, upload-time = "2025-09-09T08:20:52.627Z" }, + { url = "https://files.pythonhosted.org/packages/ae/93/a3038cb0293037fd335f77f31fe053b89c72f17b1c8908c576c29d953e84/scikit_learn-1.7.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0b7dacaa05e5d76759fb071558a8b5130f4845166d88654a0f9bdf3eb57851b7", size = 9212382, upload-time = "2025-09-09T08:20:54.731Z" }, + { url = "https://files.pythonhosted.org/packages/40/dd/9a88879b0c1104259136146e4742026b52df8540c39fec21a6383f8292c7/scikit_learn-1.7.2-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:abebbd61ad9e1deed54cca45caea8ad5f79e1b93173dece40bb8e0c658dbe6fe", size = 8592042, upload-time = "2025-09-09T08:20:57.313Z" }, + { url = "https://files.pythonhosted.org/packages/46/af/c5e286471b7d10871b811b72ae794ac5fe2989c0a2df07f0ec723030f5f5/scikit_learn-1.7.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:502c18e39849c0ea1a5d681af1dbcf15f6cce601aebb657aabbfe84133c1907f", size = 9434180, upload-time = "2025-09-09T08:20:59.671Z" }, + { url = "https://files.pythonhosted.org/packages/f1/fd/df59faa53312d585023b2da27e866524ffb8faf87a68516c23896c718320/scikit_learn-1.7.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7a4c328a71785382fe3fe676a9ecf2c86189249beff90bf85e22bdb7efaf9ae0", size = 9283660, upload-time = "2025-09-09T08:21:01.71Z" }, + { url = "https://files.pythonhosted.org/packages/a7/c7/03000262759d7b6f38c836ff9d512f438a70d8a8ddae68ee80de72dcfb63/scikit_learn-1.7.2-cp313-cp313-win_amd64.whl", hash = "sha256:63a9afd6f7b229aad94618c01c252ce9e6fa97918c5ca19c9a17a087d819440c", size = 8702057, upload-time = "2025-09-09T08:21:04.234Z" }, + { url = "https://files.pythonhosted.org/packages/55/87/ef5eb1f267084532c8e4aef98a28b6ffe7425acbfd64b5e2f2e066bc29b3/scikit_learn-1.7.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:9acb6c5e867447b4e1390930e3944a005e2cb115922e693c08a323421a6966e8", size = 9558731, upload-time = "2025-09-09T08:21:06.381Z" }, + { url = "https://files.pythonhosted.org/packages/93/f8/6c1e3fc14b10118068d7938878a9f3f4e6d7b74a8ddb1e5bed65159ccda8/scikit_learn-1.7.2-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:2a41e2a0ef45063e654152ec9d8bcfc39f7afce35b08902bfe290c2498a67a6a", size = 9038852, upload-time = "2025-09-09T08:21:08.628Z" }, + { url = "https://files.pythonhosted.org/packages/83/87/066cafc896ee540c34becf95d30375fe5cbe93c3b75a0ee9aa852cd60021/scikit_learn-1.7.2-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:98335fb98509b73385b3ab2bd0639b1f610541d3988ee675c670371d6a87aa7c", size = 9527094, upload-time = "2025-09-09T08:21:11.486Z" }, + { url = "https://files.pythonhosted.org/packages/9c/2b/4903e1ccafa1f6453b1ab78413938c8800633988c838aa0be386cbb33072/scikit_learn-1.7.2-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:191e5550980d45449126e23ed1d5e9e24b2c68329ee1f691a3987476e115e09c", size = 9367436, upload-time = "2025-09-09T08:21:13.602Z" }, + { url = "https://files.pythonhosted.org/packages/b5/aa/8444be3cfb10451617ff9d177b3c190288f4563e6c50ff02728be67ad094/scikit_learn-1.7.2-cp313-cp313t-win_amd64.whl", hash = "sha256:57dc4deb1d3762c75d685507fbd0bc17160144b2f2ba4ccea5dc285ab0d0e973", size = 9275749, upload-time = "2025-09-09T08:21:15.96Z" }, ] [[package]] name = "scipy" -version = "1.16.1" +version = "1.16.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f5/4a/b927028464795439faec8eaf0b03b011005c487bb2d07409f28bf30879c4/scipy-1.16.1.tar.gz", hash = "sha256:44c76f9e8b6e8e488a586190ab38016e4ed2f8a038af7cd3defa903c0a2238b3", size = 30580861, upload-time = "2025-07-27T16:33:30.834Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/da/91/812adc6f74409b461e3a5fa97f4f74c769016919203138a3bf6fc24ba4c5/scipy-1.16.1-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:c033fa32bab91dc98ca59d0cf23bb876454e2bb02cbe592d5023138778f70030", size = 36552519, upload-time = "2025-07-27T16:26:29.658Z" }, - { url = "https://files.pythonhosted.org/packages/47/18/8e355edcf3b71418d9e9f9acd2708cc3a6c27e8f98fde0ac34b8a0b45407/scipy-1.16.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:6e5c2f74e5df33479b5cd4e97a9104c511518fbd979aa9b8f6aec18b2e9ecae7", size = 28638010, upload-time = "2025-07-27T16:26:38.196Z" }, - { url = "https://files.pythonhosted.org/packages/d9/eb/e931853058607bdfbc11b86df19ae7a08686121c203483f62f1ecae5989c/scipy-1.16.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:0a55ffe0ba0f59666e90951971a884d1ff6f4ec3275a48f472cfb64175570f77", size = 20909790, upload-time = "2025-07-27T16:26:43.93Z" }, - { url = "https://files.pythonhosted.org/packages/45/0c/be83a271d6e96750cd0be2e000f35ff18880a46f05ce8b5d3465dc0f7a2a/scipy-1.16.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:f8a5d6cd147acecc2603fbd382fed6c46f474cccfcf69ea32582e033fb54dcfe", size = 23513352, upload-time = "2025-07-27T16:26:50.017Z" }, - { url = "https://files.pythonhosted.org/packages/7c/bf/fe6eb47e74f762f933cca962db7f2c7183acfdc4483bd1c3813cfe83e538/scipy-1.16.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cb18899127278058bcc09e7b9966d41a5a43740b5bb8dcba401bd983f82e885b", size = 33534643, upload-time = "2025-07-27T16:26:57.503Z" }, - { url = "https://files.pythonhosted.org/packages/bb/ba/63f402e74875486b87ec6506a4f93f6d8a0d94d10467280f3d9d7837ce3a/scipy-1.16.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:adccd93a2fa937a27aae826d33e3bfa5edf9aa672376a4852d23a7cd67a2e5b7", size = 35376776, upload-time = "2025-07-27T16:27:06.639Z" }, - { url = "https://files.pythonhosted.org/packages/c3/b4/04eb9d39ec26a1b939689102da23d505ea16cdae3dbb18ffc53d1f831044/scipy-1.16.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:18aca1646a29ee9a0625a1be5637fa798d4d81fdf426481f06d69af828f16958", size = 35698906, upload-time = "2025-07-27T16:27:14.943Z" }, - { url = "https://files.pythonhosted.org/packages/04/d6/bb5468da53321baeb001f6e4e0d9049eadd175a4a497709939128556e3ec/scipy-1.16.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d85495cef541729a70cdddbbf3e6b903421bc1af3e8e3a9a72a06751f33b7c39", size = 38129275, upload-time = "2025-07-27T16:27:23.873Z" }, - { url = "https://files.pythonhosted.org/packages/c4/94/994369978509f227cba7dfb9e623254d0d5559506fe994aef4bea3ed469c/scipy-1.16.1-cp311-cp311-win_amd64.whl", hash = "sha256:226652fca853008119c03a8ce71ffe1b3f6d2844cc1686e8f9806edafae68596", size = 38644572, upload-time = "2025-07-27T16:27:32.637Z" }, - { url = "https://files.pythonhosted.org/packages/f8/d9/ec4864f5896232133f51382b54a08de91a9d1af7a76dfa372894026dfee2/scipy-1.16.1-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:81b433bbeaf35728dad619afc002db9b189e45eebe2cd676effe1fb93fef2b9c", size = 36575194, upload-time = "2025-07-27T16:27:41.321Z" }, - { url = "https://files.pythonhosted.org/packages/5c/6d/40e81ecfb688e9d25d34a847dca361982a6addf8e31f0957b1a54fbfa994/scipy-1.16.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:886cc81fdb4c6903a3bb0464047c25a6d1016fef77bb97949817d0c0d79f9e04", size = 28594590, upload-time = "2025-07-27T16:27:49.204Z" }, - { url = "https://files.pythonhosted.org/packages/0e/37/9f65178edfcc629377ce9a64fc09baebea18c80a9e57ae09a52edf84880b/scipy-1.16.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:15240c3aac087a522b4eaedb09f0ad061753c5eebf1ea430859e5bf8640d5919", size = 20866458, upload-time = "2025-07-27T16:27:54.98Z" }, - { url = "https://files.pythonhosted.org/packages/2c/7b/749a66766871ea4cb1d1ea10f27004db63023074c22abed51f22f09770e0/scipy-1.16.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:65f81a25805f3659b48126b5053d9e823d3215e4a63730b5e1671852a1705921", size = 23539318, upload-time = "2025-07-27T16:28:01.604Z" }, - { url = "https://files.pythonhosted.org/packages/c4/db/8d4afec60eb833a666434d4541a3151eedbf2494ea6d4d468cbe877f00cd/scipy-1.16.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6c62eea7f607f122069b9bad3f99489ddca1a5173bef8a0c75555d7488b6f725", size = 33292899, upload-time = "2025-07-27T16:28:09.147Z" }, - { url = "https://files.pythonhosted.org/packages/51/1e/79023ca3bbb13a015d7d2757ecca3b81293c663694c35d6541b4dca53e98/scipy-1.16.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f965bbf3235b01c776115ab18f092a95aa74c271a52577bcb0563e85738fd618", size = 35162637, upload-time = "2025-07-27T16:28:17.535Z" }, - { url = "https://files.pythonhosted.org/packages/b6/49/0648665f9c29fdaca4c679182eb972935b3b4f5ace41d323c32352f29816/scipy-1.16.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f006e323874ffd0b0b816d8c6a8e7f9a73d55ab3b8c3f72b752b226d0e3ac83d", size = 35490507, upload-time = "2025-07-27T16:28:25.705Z" }, - { url = "https://files.pythonhosted.org/packages/62/8f/66cbb9d6bbb18d8c658f774904f42a92078707a7c71e5347e8bf2f52bb89/scipy-1.16.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e8fd15fc5085ab4cca74cb91fe0a4263b1f32e4420761ddae531ad60934c2119", size = 37923998, upload-time = "2025-07-27T16:28:34.339Z" }, - { url = "https://files.pythonhosted.org/packages/14/c3/61f273ae550fbf1667675701112e380881905e28448c080b23b5a181df7c/scipy-1.16.1-cp312-cp312-win_amd64.whl", hash = "sha256:f7b8013c6c066609577d910d1a2a077021727af07b6fab0ee22c2f901f22352a", size = 38508060, upload-time = "2025-07-27T16:28:43.242Z" }, - { url = "https://files.pythonhosted.org/packages/93/0b/b5c99382b839854a71ca9482c684e3472badc62620287cbbdab499b75ce6/scipy-1.16.1-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:5451606823a5e73dfa621a89948096c6528e2896e40b39248295d3a0138d594f", size = 36533717, upload-time = "2025-07-27T16:28:51.706Z" }, - { url = "https://files.pythonhosted.org/packages/eb/e5/69ab2771062c91e23e07c12e7d5033a6b9b80b0903ee709c3c36b3eb520c/scipy-1.16.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:89728678c5ca5abd610aee148c199ac1afb16e19844401ca97d43dc548a354eb", size = 28570009, upload-time = "2025-07-27T16:28:57.017Z" }, - { url = "https://files.pythonhosted.org/packages/f4/69/bd75dbfdd3cf524f4d753484d723594aed62cfaac510123e91a6686d520b/scipy-1.16.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e756d688cb03fd07de0fffad475649b03cb89bee696c98ce508b17c11a03f95c", size = 20841942, upload-time = "2025-07-27T16:29:01.152Z" }, - { url = "https://files.pythonhosted.org/packages/ea/74/add181c87663f178ba7d6144b370243a87af8476664d5435e57d599e6874/scipy-1.16.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5aa2687b9935da3ed89c5dbed5234576589dd28d0bf7cd237501ccfbdf1ad608", size = 23498507, upload-time = "2025-07-27T16:29:05.202Z" }, - { url = "https://files.pythonhosted.org/packages/1d/74/ece2e582a0d9550cee33e2e416cc96737dce423a994d12bbe59716f47ff1/scipy-1.16.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0851f6a1e537fe9399f35986897e395a1aa61c574b178c0d456be5b1a0f5ca1f", size = 33286040, upload-time = "2025-07-27T16:29:10.201Z" }, - { url = "https://files.pythonhosted.org/packages/e4/82/08e4076df538fb56caa1d489588d880ec7c52d8273a606bb54d660528f7c/scipy-1.16.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fedc2cbd1baed37474b1924c331b97bdff611d762c196fac1a9b71e67b813b1b", size = 35176096, upload-time = "2025-07-27T16:29:17.091Z" }, - { url = "https://files.pythonhosted.org/packages/fa/79/cd710aab8c921375711a8321c6be696e705a120e3011a643efbbcdeeabcc/scipy-1.16.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2ef500e72f9623a6735769e4b93e9dcb158d40752cdbb077f305487e3e2d1f45", size = 35490328, upload-time = "2025-07-27T16:29:22.928Z" }, - { url = "https://files.pythonhosted.org/packages/71/73/e9cc3d35ee4526d784520d4494a3e1ca969b071fb5ae5910c036a375ceec/scipy-1.16.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:978d8311674b05a8f7ff2ea6c6bce5d8b45a0cb09d4c5793e0318f448613ea65", size = 37939921, upload-time = "2025-07-27T16:29:29.108Z" }, - { url = "https://files.pythonhosted.org/packages/21/12/c0efd2941f01940119b5305c375ae5c0fcb7ec193f806bd8f158b73a1782/scipy-1.16.1-cp313-cp313-win_amd64.whl", hash = "sha256:81929ed0fa7a5713fcdd8b2e6f73697d3b4c4816d090dd34ff937c20fa90e8ab", size = 38479462, upload-time = "2025-07-27T16:30:24.078Z" }, - { url = "https://files.pythonhosted.org/packages/7a/19/c3d08b675260046a991040e1ea5d65f91f40c7df1045fffff412dcfc6765/scipy-1.16.1-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:bcc12db731858abda693cecdb3bdc9e6d4bd200213f49d224fe22df82687bdd6", size = 36938832, upload-time = "2025-07-27T16:29:35.057Z" }, - { url = "https://files.pythonhosted.org/packages/81/f2/ce53db652c033a414a5b34598dba6b95f3d38153a2417c5a3883da429029/scipy-1.16.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:744d977daa4becb9fc59135e75c069f8d301a87d64f88f1e602a9ecf51e77b27", size = 29093084, upload-time = "2025-07-27T16:29:40.201Z" }, - { url = "https://files.pythonhosted.org/packages/a9/ae/7a10ff04a7dc15f9057d05b33737ade244e4bd195caa3f7cc04d77b9e214/scipy-1.16.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:dc54f76ac18073bcecffb98d93f03ed6b81a92ef91b5d3b135dcc81d55a724c7", size = 21365098, upload-time = "2025-07-27T16:29:44.295Z" }, - { url = "https://files.pythonhosted.org/packages/36/ac/029ff710959932ad3c2a98721b20b405f05f752f07344622fd61a47c5197/scipy-1.16.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:367d567ee9fc1e9e2047d31f39d9d6a7a04e0710c86e701e053f237d14a9b4f6", size = 23896858, upload-time = "2025-07-27T16:29:48.784Z" }, - { url = "https://files.pythonhosted.org/packages/71/13/d1ef77b6bd7898720e1f0b6b3743cb945f6c3cafa7718eaac8841035ab60/scipy-1.16.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4cf5785e44e19dcd32a0e4807555e1e9a9b8d475c6afff3d21c3c543a6aa84f4", size = 33438311, upload-time = "2025-07-27T16:29:54.164Z" }, - { url = "https://files.pythonhosted.org/packages/2d/e0/e64a6821ffbb00b4c5b05169f1c1fddb4800e9307efe3db3788995a82a2c/scipy-1.16.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3d0b80fb26d3e13a794c71d4b837e2a589d839fd574a6bbb4ee1288c213ad4a3", size = 35279542, upload-time = "2025-07-27T16:30:00.249Z" }, - { url = "https://files.pythonhosted.org/packages/57/59/0dc3c8b43e118f1e4ee2b798dcc96ac21bb20014e5f1f7a8e85cc0653bdb/scipy-1.16.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8503517c44c18d1030d666cb70aaac1cc8913608816e06742498833b128488b7", size = 35667665, upload-time = "2025-07-27T16:30:05.916Z" }, - { url = "https://files.pythonhosted.org/packages/45/5f/844ee26e34e2f3f9f8febb9343748e72daeaec64fe0c70e9bf1ff84ec955/scipy-1.16.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:30cc4bb81c41831ecfd6dc450baf48ffd80ef5aed0f5cf3ea775740e80f16ecc", size = 38045210, upload-time = "2025-07-27T16:30:11.655Z" }, - { url = "https://files.pythonhosted.org/packages/8d/d7/210f2b45290f444f1de64bc7353aa598ece9f0e90c384b4a156f9b1a5063/scipy-1.16.1-cp313-cp313t-win_amd64.whl", hash = "sha256:c24fa02f7ed23ae514460a22c57eca8f530dbfa50b1cfdbf4f37c05b5309cc39", size = 38593661, upload-time = "2025-07-27T16:30:17.825Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/4c/3b/546a6f0bfe791bbb7f8d591613454d15097e53f906308ec6f7c1ce588e8e/scipy-1.16.2.tar.gz", hash = "sha256:af029b153d243a80afb6eabe40b0a07f8e35c9adc269c019f364ad747f826a6b", size = 30580599, upload-time = "2025-09-11T17:48:08.271Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/ef/37ed4b213d64b48422df92560af7300e10fe30b5d665dd79932baebee0c6/scipy-1.16.2-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:6ab88ea43a57da1af33292ebd04b417e8e2eaf9d5aa05700be8d6e1b6501cd92", size = 36619956, upload-time = "2025-09-11T17:39:20.5Z" }, + { url = "https://files.pythonhosted.org/packages/85/ab/5c2eba89b9416961a982346a4d6a647d78c91ec96ab94ed522b3b6baf444/scipy-1.16.2-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:c95e96c7305c96ede73a7389f46ccd6c659c4da5ef1b2789466baeaed3622b6e", size = 28931117, upload-time = "2025-09-11T17:39:29.06Z" }, + { url = "https://files.pythonhosted.org/packages/80/d1/eed51ab64d227fe60229a2d57fb60ca5898cfa50ba27d4f573e9e5f0b430/scipy-1.16.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:87eb178db04ece7c698220d523c170125dbffebb7af0345e66c3554f6f60c173", size = 20921997, upload-time = "2025-09-11T17:39:34.892Z" }, + { url = "https://files.pythonhosted.org/packages/be/7c/33ea3e23bbadde96726edba6bf9111fb1969d14d9d477ffa202c67bec9da/scipy-1.16.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:4e409eac067dcee96a57fbcf424c13f428037827ec7ee3cb671ff525ca4fc34d", size = 23523374, upload-time = "2025-09-11T17:39:40.846Z" }, + { url = "https://files.pythonhosted.org/packages/96/0b/7399dc96e1e3f9a05e258c98d716196a34f528eef2ec55aad651ed136d03/scipy-1.16.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e574be127bb760f0dad24ff6e217c80213d153058372362ccb9555a10fc5e8d2", size = 33583702, upload-time = "2025-09-11T17:39:49.011Z" }, + { url = "https://files.pythonhosted.org/packages/1a/bc/a5c75095089b96ea72c1bd37a4497c24b581ec73db4ef58ebee142ad2d14/scipy-1.16.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f5db5ba6188d698ba7abab982ad6973265b74bb40a1efe1821b58c87f73892b9", size = 35883427, upload-time = "2025-09-11T17:39:57.406Z" }, + { url = "https://files.pythonhosted.org/packages/ab/66/e25705ca3d2b87b97fe0a278a24b7f477b4023a926847935a1a71488a6a6/scipy-1.16.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ec6e74c4e884104ae006d34110677bfe0098203a3fec2f3faf349f4cb05165e3", size = 36212940, upload-time = "2025-09-11T17:40:06.013Z" }, + { url = "https://files.pythonhosted.org/packages/d6/fd/0bb911585e12f3abdd603d721d83fc1c7492835e1401a0e6d498d7822b4b/scipy-1.16.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:912f46667d2d3834bc3d57361f854226475f695eb08c08a904aadb1c936b6a88", size = 38865092, upload-time = "2025-09-11T17:40:15.143Z" }, + { url = "https://files.pythonhosted.org/packages/d6/73/c449a7d56ba6e6f874183759f8483cde21f900a8be117d67ffbb670c2958/scipy-1.16.2-cp311-cp311-win_amd64.whl", hash = "sha256:91e9e8a37befa5a69e9cacbe0bcb79ae5afb4a0b130fd6db6ee6cc0d491695fa", size = 38687626, upload-time = "2025-09-11T17:40:24.041Z" }, + { url = "https://files.pythonhosted.org/packages/68/72/02f37316adf95307f5d9e579023c6899f89ff3a051fa079dbd6faafc48e5/scipy-1.16.2-cp311-cp311-win_arm64.whl", hash = "sha256:f3bf75a6dcecab62afde4d1f973f1692be013110cad5338007927db8da73249c", size = 25503506, upload-time = "2025-09-11T17:40:30.703Z" }, + { url = "https://files.pythonhosted.org/packages/b7/8d/6396e00db1282279a4ddd507c5f5e11f606812b608ee58517ce8abbf883f/scipy-1.16.2-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:89d6c100fa5c48472047632e06f0876b3c4931aac1f4291afc81a3644316bb0d", size = 36646259, upload-time = "2025-09-11T17:40:39.329Z" }, + { url = "https://files.pythonhosted.org/packages/3b/93/ea9edd7e193fceb8eef149804491890bde73fb169c896b61aa3e2d1e4e77/scipy-1.16.2-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:ca748936cd579d3f01928b30a17dc474550b01272d8046e3e1ee593f23620371", size = 28888976, upload-time = "2025-09-11T17:40:46.82Z" }, + { url = "https://files.pythonhosted.org/packages/91/4d/281fddc3d80fd738ba86fd3aed9202331180b01e2c78eaae0642f22f7e83/scipy-1.16.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:fac4f8ce2ddb40e2e3d0f7ec36d2a1e7f92559a2471e59aec37bd8d9de01fec0", size = 20879905, upload-time = "2025-09-11T17:40:52.545Z" }, + { url = "https://files.pythonhosted.org/packages/69/40/b33b74c84606fd301b2915f0062e45733c6ff5708d121dd0deaa8871e2d0/scipy-1.16.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:033570f1dcefd79547a88e18bccacff025c8c647a330381064f561d43b821232", size = 23553066, upload-time = "2025-09-11T17:40:59.014Z" }, + { url = "https://files.pythonhosted.org/packages/55/a7/22c739e2f21a42cc8f16bc76b47cff4ed54fbe0962832c589591c2abec34/scipy-1.16.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ea3421209bf00c8a5ef2227de496601087d8f638a2363ee09af059bd70976dc1", size = 33336407, upload-time = "2025-09-11T17:41:06.796Z" }, + { url = "https://files.pythonhosted.org/packages/53/11/a0160990b82999b45874dc60c0c183d3a3a969a563fffc476d5a9995c407/scipy-1.16.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f66bd07ba6f84cd4a380b41d1bf3c59ea488b590a2ff96744845163309ee8e2f", size = 35673281, upload-time = "2025-09-11T17:41:15.055Z" }, + { url = "https://files.pythonhosted.org/packages/96/53/7ef48a4cfcf243c3d0f1643f5887c81f29fdf76911c4e49331828e19fc0a/scipy-1.16.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e9feab931bd2aea4a23388c962df6468af3d808ddf2d40f94a81c5dc38f32ef", size = 36004222, upload-time = "2025-09-11T17:41:23.868Z" }, + { url = "https://files.pythonhosted.org/packages/49/7f/71a69e0afd460049d41c65c630c919c537815277dfea214031005f474d78/scipy-1.16.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:03dfc75e52f72cf23ec2ced468645321407faad8f0fe7b1f5b49264adbc29cb1", size = 38664586, upload-time = "2025-09-11T17:41:31.021Z" }, + { url = "https://files.pythonhosted.org/packages/34/95/20e02ca66fb495a95fba0642fd48e0c390d0ece9b9b14c6e931a60a12dea/scipy-1.16.2-cp312-cp312-win_amd64.whl", hash = "sha256:0ce54e07bbb394b417457409a64fd015be623f36e330ac49306433ffe04bc97e", size = 38550641, upload-time = "2025-09-11T17:41:36.61Z" }, + { url = "https://files.pythonhosted.org/packages/92/ad/13646b9beb0a95528ca46d52b7babafbe115017814a611f2065ee4e61d20/scipy-1.16.2-cp312-cp312-win_arm64.whl", hash = "sha256:2a8ffaa4ac0df81a0b94577b18ee079f13fecdb924df3328fc44a7dc5ac46851", size = 25456070, upload-time = "2025-09-11T17:41:41.3Z" }, + { url = "https://files.pythonhosted.org/packages/c1/27/c5b52f1ee81727a9fc457f5ac1e9bf3d6eab311805ea615c83c27ba06400/scipy-1.16.2-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:84f7bf944b43e20b8a894f5fe593976926744f6c185bacfcbdfbb62736b5cc70", size = 36604856, upload-time = "2025-09-11T17:41:47.695Z" }, + { url = "https://files.pythonhosted.org/packages/32/a9/15c20d08e950b540184caa8ced675ba1128accb0e09c653780ba023a4110/scipy-1.16.2-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:5c39026d12edc826a1ef2ad35ad1e6d7f087f934bb868fc43fa3049c8b8508f9", size = 28864626, upload-time = "2025-09-11T17:41:52.642Z" }, + { url = "https://files.pythonhosted.org/packages/4c/fc/ea36098df653cca26062a627c1a94b0de659e97127c8491e18713ca0e3b9/scipy-1.16.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e52729ffd45b68777c5319560014d6fd251294200625d9d70fd8626516fc49f5", size = 20855689, upload-time = "2025-09-11T17:41:57.886Z" }, + { url = "https://files.pythonhosted.org/packages/dc/6f/d0b53be55727f3e6d7c72687ec18ea6d0047cf95f1f77488b99a2bafaee1/scipy-1.16.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:024dd4a118cccec09ca3209b7e8e614931a6ffb804b2a601839499cb88bdf925", size = 23512151, upload-time = "2025-09-11T17:42:02.303Z" }, + { url = "https://files.pythonhosted.org/packages/11/85/bf7dab56e5c4b1d3d8eef92ca8ede788418ad38a7dc3ff50262f00808760/scipy-1.16.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7a5dc7ee9c33019973a470556081b0fd3c9f4c44019191039f9769183141a4d9", size = 33329824, upload-time = "2025-09-11T17:42:07.549Z" }, + { url = "https://files.pythonhosted.org/packages/da/6a/1a927b14ddc7714111ea51f4e568203b2bb6ed59bdd036d62127c1a360c8/scipy-1.16.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c2275ff105e508942f99d4e3bc56b6ef5e4b3c0af970386ca56b777608ce95b7", size = 35681881, upload-time = "2025-09-11T17:42:13.255Z" }, + { url = "https://files.pythonhosted.org/packages/c1/5f/331148ea5780b4fcc7007a4a6a6ee0a0c1507a796365cc642d4d226e1c3a/scipy-1.16.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:af80196eaa84f033e48444d2e0786ec47d328ba00c71e4299b602235ffef9acb", size = 36006219, upload-time = "2025-09-11T17:42:18.765Z" }, + { url = "https://files.pythonhosted.org/packages/46/3a/e991aa9d2aec723b4a8dcfbfc8365edec5d5e5f9f133888067f1cbb7dfc1/scipy-1.16.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9fb1eb735fe3d6ed1f89918224e3385fbf6f9e23757cacc35f9c78d3b712dd6e", size = 38682147, upload-time = "2025-09-11T17:42:25.177Z" }, + { url = "https://files.pythonhosted.org/packages/a1/57/0f38e396ad19e41b4c5db66130167eef8ee620a49bc7d0512e3bb67e0cab/scipy-1.16.2-cp313-cp313-win_amd64.whl", hash = "sha256:fda714cf45ba43c9d3bae8f2585c777f64e3f89a2e073b668b32ede412d8f52c", size = 38520766, upload-time = "2025-09-11T17:43:25.342Z" }, + { url = "https://files.pythonhosted.org/packages/1b/a5/85d3e867b6822d331e26c862a91375bb7746a0b458db5effa093d34cdb89/scipy-1.16.2-cp313-cp313-win_arm64.whl", hash = "sha256:2f5350da923ccfd0b00e07c3e5cfb316c1c0d6c1d864c07a72d092e9f20db104", size = 25451169, upload-time = "2025-09-11T17:43:30.198Z" }, + { url = "https://files.pythonhosted.org/packages/09/d9/60679189bcebda55992d1a45498de6d080dcaf21ce0c8f24f888117e0c2d/scipy-1.16.2-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:53d8d2ee29b925344c13bda64ab51785f016b1b9617849dac10897f0701b20c1", size = 37012682, upload-time = "2025-09-11T17:42:30.677Z" }, + { url = "https://files.pythonhosted.org/packages/83/be/a99d13ee4d3b7887a96f8c71361b9659ba4ef34da0338f14891e102a127f/scipy-1.16.2-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:9e05e33657efb4c6a9d23bd8300101536abd99c85cca82da0bffff8d8764d08a", size = 29389926, upload-time = "2025-09-11T17:42:35.845Z" }, + { url = "https://files.pythonhosted.org/packages/bf/0a/130164a4881cec6ca8c00faf3b57926f28ed429cd6001a673f83c7c2a579/scipy-1.16.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:7fe65b36036357003b3ef9d37547abeefaa353b237e989c21027b8ed62b12d4f", size = 21381152, upload-time = "2025-09-11T17:42:40.07Z" }, + { url = "https://files.pythonhosted.org/packages/47/a6/503ffb0310ae77fba874e10cddfc4a1280bdcca1d13c3751b8c3c2996cf8/scipy-1.16.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:6406d2ac6d40b861cccf57f49592f9779071655e9f75cd4f977fa0bdd09cb2e4", size = 23914410, upload-time = "2025-09-11T17:42:44.313Z" }, + { url = "https://files.pythonhosted.org/packages/fa/c7/1147774bcea50d00c02600aadaa919facbd8537997a62496270133536ed6/scipy-1.16.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ff4dc42bd321991fbf611c23fc35912d690f731c9914bf3af8f417e64aca0f21", size = 33481880, upload-time = "2025-09-11T17:42:49.325Z" }, + { url = "https://files.pythonhosted.org/packages/6a/74/99d5415e4c3e46b2586f30cdbecb95e101c7192628a484a40dd0d163811a/scipy-1.16.2-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:654324826654d4d9133e10675325708fb954bc84dae6e9ad0a52e75c6b1a01d7", size = 35791425, upload-time = "2025-09-11T17:42:54.711Z" }, + { url = "https://files.pythonhosted.org/packages/1b/ee/a6559de7c1cc710e938c0355d9d4fbcd732dac4d0d131959d1f3b63eb29c/scipy-1.16.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:63870a84cd15c44e65220eaed2dac0e8f8b26bbb991456a033c1d9abfe8a94f8", size = 36178622, upload-time = "2025-09-11T17:43:00.375Z" }, + { url = "https://files.pythonhosted.org/packages/4e/7b/f127a5795d5ba8ece4e0dce7d4a9fb7cb9e4f4757137757d7a69ab7d4f1a/scipy-1.16.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:fa01f0f6a3050fa6a9771a95d5faccc8e2f5a92b4a2e5440a0fa7264a2398472", size = 38783985, upload-time = "2025-09-11T17:43:06.661Z" }, + { url = "https://files.pythonhosted.org/packages/3e/9f/bc81c1d1e033951eb5912cd3750cc005943afa3e65a725d2443a3b3c4347/scipy-1.16.2-cp313-cp313t-win_amd64.whl", hash = "sha256:116296e89fba96f76353a8579820c2512f6e55835d3fad7780fece04367de351", size = 38631367, upload-time = "2025-09-11T17:43:14.44Z" }, + { url = "https://files.pythonhosted.org/packages/d6/5e/2cc7555fd81d01814271412a1d59a289d25f8b63208a0a16c21069d55d3e/scipy-1.16.2-cp313-cp313t-win_arm64.whl", hash = "sha256:98e22834650be81d42982360382b43b17f7ba95e0e6993e2a4f5b9ad9283a94d", size = 25787992, upload-time = "2025-09-11T17:43:19.745Z" }, ] [[package]] name = "scipy-stubs" -version = "1.16.1.1" +version = "1.16.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "optype", extra = ["numpy"] }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ab/7e/978c7cad40405cb927d065c31bfaefbc09b4f6cf1ce97e4af6625b1935ab/scipy_stubs-1.16.1.1.tar.gz", hash = "sha256:5b36fdcc1a66cc530c08917fa7c7499ec7a607487735419c677742dcf25803fb", size = 347578, upload-time = "2025-08-21T00:57:31.306Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4b/84/b4c2caf7748f331870992e7ede5b5df0b080671bcef8c8c7e27a3cf8694a/scipy_stubs-1.16.2.0.tar.gz", hash = "sha256:8fdd45155fca401bb755b1b63ac2f192f84f25c3be8da2c99d1cafb2708f3052", size = 352676, upload-time = "2025-09-11T23:28:59.236Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fa/1b/8c2b4f0e957ad23d30419c01e9ef874284c09ceb942daf3a6546ffd51e6e/scipy_stubs-1.16.1.1-py3-none-any.whl", hash = "sha256:8c3e98a5a7def79570cbd6e2f4316da570d48b7945a630ac016b199d12c31918", size = 553763, upload-time = "2025-08-21T00:57:27.649Z" }, + { url = "https://files.pythonhosted.org/packages/83/c8/67d984c264f759e7653c130a4b12ae3b4f4304867579560e9a869adb7883/scipy_stubs-1.16.2.0-py3-none-any.whl", hash = "sha256:18c50d49e3c932033fdd4f7fa4fea9e45c8787f92bceaec9e86ccbd140e835d5", size = 553247, upload-time = "2025-09-11T23:28:57.688Z" }, ] [[package]] @@ -3068,11 +3089,11 @@ wheels = [ [[package]] name = "session-info2" -version = "0.2.1" +version = "0.2.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/82/e6/29acd849dbc37ad80e251834e2759f0acf1ae33864781455aa1d5b051ce6/session_info2-0.2.1.tar.gz", hash = "sha256:f2aa4ae95db7f40239608217d7c077b6a51bc3d897792010ea3794ea799bd69c", size = 23257, upload-time = "2025-08-20T15:43:00.938Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/b3/d4988e243956a19314a2d470e8db3eb881dd4fc852cd0642b17341f88947/session_info2-0.2.2.tar.gz", hash = "sha256:48a2bc0e8fc39d74e49dc2c273346efac2735303bc874ee591190c8dae100f9a", size = 23788, upload-time = "2025-09-12T12:29:49.523Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/91/a2/8575bc8036ee4f96043cd6b4433b3adc120aa365a6b7aef19f564c99cbb7/session_info2-0.2.1-py3-none-any.whl", hash = "sha256:2554f974441fe5a230d45ef5389cfaf663af7ff41520b488a633c03743f34658", size = 16066, upload-time = "2025-08-20T15:42:59.535Z" }, + { url = "https://files.pythonhosted.org/packages/89/69/1e43007a356af28c95ca92a877cabec2b18a0f9484c2480677c0d590ed62/session_info2-0.2.2-py3-none-any.whl", hash = "sha256:3284dc1e6e3fc423770681498bbfea4b1992db756bd0400288aad693d000583d", size = 16251, upload-time = "2025-09-12T12:29:48.341Z" }, ] [[package]] @@ -3086,50 +3107,50 @@ wheels = [ [[package]] name = "simplejson" -version = "3.20.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/92/51b417685abd96b31308b61b9acce7ec50d8e1de8fbc39a7fd4962c60689/simplejson-3.20.1.tar.gz", hash = "sha256:e64139b4ec4f1f24c142ff7dcafe55a22b811a74d86d66560c8815687143037d", size = 85591, upload-time = "2025-02-15T05:18:53.15Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/76/59/74bc90d1c051bc2432c96b34bd4e8036875ab58b4fcbe4d6a5a76985f853/simplejson-3.20.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:325b8c107253d3217e89d7b50c71015b5b31e2433e6c5bf38967b2f80630a8ca", size = 92132, upload-time = "2025-02-15T05:16:15.743Z" }, - { url = "https://files.pythonhosted.org/packages/71/c7/1970916e0c51794fff89f76da2f632aaf0b259b87753c88a8c409623d3e1/simplejson-3.20.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:88a7baa8211089b9e58d78fbc1b0b322103f3f3d459ff16f03a36cece0d0fcf0", size = 74956, upload-time = "2025-02-15T05:16:17.062Z" }, - { url = "https://files.pythonhosted.org/packages/c8/0d/98cc5909180463f1d75fac7180de62d4cdb4e82c4fef276b9e591979372c/simplejson-3.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:299b1007b8101d50d95bc0db1bf5c38dc372e85b504cf77f596462083ee77e3f", size = 74772, upload-time = "2025-02-15T05:16:19.204Z" }, - { url = "https://files.pythonhosted.org/packages/e1/94/a30a5211a90d67725a3e8fcc1c788189f2ae2ed2b96b63ed15d0b7f5d6bb/simplejson-3.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03ec618ed65caab48e81e3ed29586236a8e57daef792f1f3bb59504a7e98cd10", size = 143575, upload-time = "2025-02-15T05:16:21.337Z" }, - { url = "https://files.pythonhosted.org/packages/ee/08/cdb6821f1058eb5db46d252de69ff7e6c53f05f1bae6368fe20d5b51d37e/simplejson-3.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd2cdead1d3197f0ff43373cf4730213420523ba48697743e135e26f3d179f38", size = 153241, upload-time = "2025-02-15T05:16:22.859Z" }, - { url = "https://files.pythonhosted.org/packages/4c/2d/ca3caeea0bdc5efc5503d5f57a2dfb56804898fb196dfada121323ee0ccb/simplejson-3.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3466d2839fdc83e1af42e07b90bc8ff361c4e8796cd66722a40ba14e458faddd", size = 141500, upload-time = "2025-02-15T05:16:25.068Z" }, - { url = "https://files.pythonhosted.org/packages/e1/33/d3e0779d5c58245e7370c98eb969275af6b7a4a5aec3b97cbf85f09ad328/simplejson-3.20.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d492ed8e92f3a9f9be829205f44b1d0a89af6582f0cf43e0d129fa477b93fe0c", size = 144757, upload-time = "2025-02-15T05:16:28.301Z" }, - { url = "https://files.pythonhosted.org/packages/54/53/2d93128bb55861b2fa36c5944f38da51a0bc6d83e513afc6f7838440dd15/simplejson-3.20.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f924b485537b640dc69434565463fd6fc0c68c65a8c6e01a823dd26c9983cf79", size = 144409, upload-time = "2025-02-15T05:16:29.687Z" }, - { url = "https://files.pythonhosted.org/packages/99/4c/dac310a98f897ad3435b4bdc836d92e78f09e38c5dbf28211ed21dc59fa2/simplejson-3.20.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9e8eacf6a3491bf76ea91a8d46726368a6be0eb94993f60b8583550baae9439e", size = 146082, upload-time = "2025-02-15T05:16:31.064Z" }, - { url = "https://files.pythonhosted.org/packages/ee/22/d7ba958cfed39827335b82656b1c46f89678faecda9a7677b47e87b48ee6/simplejson-3.20.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d34d04bf90b4cea7c22d8b19091633908f14a096caa301b24c2f3d85b5068fb8", size = 154339, upload-time = "2025-02-15T05:16:32.719Z" }, - { url = "https://files.pythonhosted.org/packages/b8/c8/b072b741129406a7086a0799c6f5d13096231bf35fdd87a0cffa789687fc/simplejson-3.20.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:69dd28d4ce38390ea4aaf212902712c0fd1093dc4c1ff67e09687c3c3e15a749", size = 147915, upload-time = "2025-02-15T05:16:34.291Z" }, - { url = "https://files.pythonhosted.org/packages/6c/46/8347e61e9cf3db5342a42f7fd30a81b4f5cf85977f916852d7674a540907/simplejson-3.20.1-cp311-cp311-win32.whl", hash = "sha256:dfe7a9da5fd2a3499436cd350f31539e0a6ded5da6b5b3d422df016444d65e43", size = 73972, upload-time = "2025-02-15T05:16:35.712Z" }, - { url = "https://files.pythonhosted.org/packages/01/85/b52f24859237b4e9d523d5655796d911ba3d46e242eb1959c45b6af5aedd/simplejson-3.20.1-cp311-cp311-win_amd64.whl", hash = "sha256:896a6c04d7861d507d800da7642479c3547060bf97419d9ef73d98ced8258766", size = 75595, upload-time = "2025-02-15T05:16:36.957Z" }, - { url = "https://files.pythonhosted.org/packages/8d/eb/34c16a1ac9ba265d024dc977ad84e1659d931c0a700967c3e59a98ed7514/simplejson-3.20.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f31c4a3a7ab18467ee73a27f3e59158255d1520f3aad74315edde7a940f1be23", size = 93100, upload-time = "2025-02-15T05:16:38.801Z" }, - { url = "https://files.pythonhosted.org/packages/41/fc/2c2c007d135894971e6814e7c0806936e5bade28f8db4dd7e2a58b50debd/simplejson-3.20.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:884e6183d16b725e113b83a6fc0230152ab6627d4d36cb05c89c2c5bccfa7bc6", size = 75464, upload-time = "2025-02-15T05:16:40.905Z" }, - { url = "https://files.pythonhosted.org/packages/0f/05/2b5ecb33b776c34bb5cace5de5d7669f9b60e3ca13c113037b2ca86edfbd/simplejson-3.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:03d7a426e416fe0d3337115f04164cd9427eb4256e843a6b8751cacf70abc832", size = 75112, upload-time = "2025-02-15T05:16:42.246Z" }, - { url = "https://files.pythonhosted.org/packages/fe/36/1f3609a2792f06cd4b71030485f78e91eb09cfd57bebf3116bf2980a8bac/simplejson-3.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:000602141d0bddfcff60ea6a6e97d5e10c9db6b17fd2d6c66199fa481b6214bb", size = 150182, upload-time = "2025-02-15T05:16:43.557Z" }, - { url = "https://files.pythonhosted.org/packages/2f/b0/053fbda38b8b602a77a4f7829def1b4f316cd8deb5440a6d3ee90790d2a4/simplejson-3.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:af8377a8af78226e82e3a4349efdde59ffa421ae88be67e18cef915e4023a595", size = 158363, upload-time = "2025-02-15T05:16:45.748Z" }, - { url = "https://files.pythonhosted.org/packages/d1/4b/2eb84ae867539a80822e92f9be4a7200dffba609275faf99b24141839110/simplejson-3.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15c7de4c88ab2fbcb8781a3b982ef883696736134e20b1210bca43fb42ff1acf", size = 148415, upload-time = "2025-02-15T05:16:47.861Z" }, - { url = "https://files.pythonhosted.org/packages/e0/bd/400b0bd372a5666addf2540c7358bfc3841b9ce5cdbc5cc4ad2f61627ad8/simplejson-3.20.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:455a882ff3f97d810709f7b620007d4e0aca8da71d06fc5c18ba11daf1c4df49", size = 152213, upload-time = "2025-02-15T05:16:49.25Z" }, - { url = "https://files.pythonhosted.org/packages/50/12/143f447bf6a827ee9472693768dc1a5eb96154f8feb140a88ce6973a3cfa/simplejson-3.20.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:fc0f523ce923e7f38eb67804bc80e0a028c76d7868500aa3f59225574b5d0453", size = 150048, upload-time = "2025-02-15T05:16:51.5Z" }, - { url = "https://files.pythonhosted.org/packages/5e/ea/dd9b3e8e8ed710a66f24a22c16a907c9b539b6f5f45fd8586bd5c231444e/simplejson-3.20.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:76461ec929282dde4a08061071a47281ad939d0202dc4e63cdd135844e162fbc", size = 151668, upload-time = "2025-02-15T05:16:53Z" }, - { url = "https://files.pythonhosted.org/packages/99/af/ee52a8045426a0c5b89d755a5a70cc821815ef3c333b56fbcad33c4435c0/simplejson-3.20.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ab19c2da8c043607bde4d4ef3a6b633e668a7d2e3d56f40a476a74c5ea71949f", size = 158840, upload-time = "2025-02-15T05:16:54.851Z" }, - { url = "https://files.pythonhosted.org/packages/68/db/ab32869acea6b5de7d75fa0dac07a112ded795d41eaa7e66c7813b17be95/simplejson-3.20.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b2578bedaedf6294415197b267d4ef678fea336dd78ee2a6d2f4b028e9d07be3", size = 154212, upload-time = "2025-02-15T05:16:56.318Z" }, - { url = "https://files.pythonhosted.org/packages/fa/7a/e3132d454977d75a3bf9a6d541d730f76462ebf42a96fea2621498166f41/simplejson-3.20.1-cp312-cp312-win32.whl", hash = "sha256:339f407373325a36b7fd744b688ba5bae0666b5d340ec6d98aebc3014bf3d8ea", size = 74101, upload-time = "2025-02-15T05:16:57.746Z" }, - { url = "https://files.pythonhosted.org/packages/bc/5d/4e243e937fa3560107c69f6f7c2eed8589163f5ed14324e864871daa2dd9/simplejson-3.20.1-cp312-cp312-win_amd64.whl", hash = "sha256:627d4486a1ea7edf1f66bb044ace1ce6b4c1698acd1b05353c97ba4864ea2e17", size = 75736, upload-time = "2025-02-15T05:16:59.017Z" }, - { url = "https://files.pythonhosted.org/packages/c4/03/0f453a27877cb5a5fff16a975925f4119102cc8552f52536b9a98ef0431e/simplejson-3.20.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:71e849e7ceb2178344998cbe5ade101f1b329460243c79c27fbfc51c0447a7c3", size = 93109, upload-time = "2025-02-15T05:17:00.377Z" }, - { url = "https://files.pythonhosted.org/packages/74/1f/a729f4026850cabeaff23e134646c3f455e86925d2533463420635ae54de/simplejson-3.20.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b63fdbab29dc3868d6f009a59797cefaba315fd43cd32ddd998ee1da28e50e29", size = 75475, upload-time = "2025-02-15T05:17:02.544Z" }, - { url = "https://files.pythonhosted.org/packages/e2/14/50a2713fee8ff1f8d655b1a14f4a0f1c0c7246768a1b3b3d12964a4ed5aa/simplejson-3.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1190f9a3ce644fd50ec277ac4a98c0517f532cfebdcc4bd975c0979a9f05e1fb", size = 75112, upload-time = "2025-02-15T05:17:03.875Z" }, - { url = "https://files.pythonhosted.org/packages/45/86/ea9835abb646755140e2d482edc9bc1e91997ed19a59fd77ae4c6a0facea/simplejson-3.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1336ba7bcb722ad487cd265701ff0583c0bb6de638364ca947bb84ecc0015d1", size = 150245, upload-time = "2025-02-15T05:17:06.899Z" }, - { url = "https://files.pythonhosted.org/packages/12/b4/53084809faede45da829fe571c65fbda8479d2a5b9c633f46b74124d56f5/simplejson-3.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e975aac6a5acd8b510eba58d5591e10a03e3d16c1cf8a8624ca177491f7230f0", size = 158465, upload-time = "2025-02-15T05:17:08.707Z" }, - { url = "https://files.pythonhosted.org/packages/a9/7d/d56579468d1660b3841e1f21c14490d103e33cf911886b22652d6e9683ec/simplejson-3.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6a6dd11ee282937ad749da6f3b8d87952ad585b26e5edfa10da3ae2536c73078", size = 148514, upload-time = "2025-02-15T05:17:11.323Z" }, - { url = "https://files.pythonhosted.org/packages/19/e3/874b1cca3d3897b486d3afdccc475eb3a09815bf1015b01cf7fcb52a55f0/simplejson-3.20.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab980fcc446ab87ea0879edad41a5c28f2d86020014eb035cf5161e8de4474c6", size = 152262, upload-time = "2025-02-15T05:17:13.543Z" }, - { url = "https://files.pythonhosted.org/packages/32/84/f0fdb3625292d945c2bd13a814584603aebdb38cfbe5fe9be6b46fe598c4/simplejson-3.20.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f5aee2a4cb6b146bd17333ac623610f069f34e8f31d2f4f0c1a2186e50c594f0", size = 150164, upload-time = "2025-02-15T05:17:15.021Z" }, - { url = "https://files.pythonhosted.org/packages/95/51/6d625247224f01eaaeabace9aec75ac5603a42f8ebcce02c486fbda8b428/simplejson-3.20.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:652d8eecbb9a3b6461b21ec7cf11fd0acbab144e45e600c817ecf18e4580b99e", size = 151795, upload-time = "2025-02-15T05:17:16.542Z" }, - { url = "https://files.pythonhosted.org/packages/7f/d9/bb921df6b35be8412f519e58e86d1060fddf3ad401b783e4862e0a74c4c1/simplejson-3.20.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:8c09948f1a486a89251ee3a67c9f8c969b379f6ffff1a6064b41fea3bce0a112", size = 159027, upload-time = "2025-02-15T05:17:18.083Z" }, - { url = "https://files.pythonhosted.org/packages/03/c5/5950605e4ad023a6621cf4c931b29fd3d2a9c1f36be937230bfc83d7271d/simplejson-3.20.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:cbbd7b215ad4fc6f058b5dd4c26ee5c59f72e031dfda3ac183d7968a99e4ca3a", size = 154380, upload-time = "2025-02-15T05:17:20.334Z" }, - { url = "https://files.pythonhosted.org/packages/66/ad/b74149557c5ec1e4e4d55758bda426f5d2ec0123cd01a53ae63b8de51fa3/simplejson-3.20.1-cp313-cp313-win32.whl", hash = "sha256:ae81e482476eaa088ef9d0120ae5345de924f23962c0c1e20abbdff597631f87", size = 74102, upload-time = "2025-02-15T05:17:22.475Z" }, - { url = "https://files.pythonhosted.org/packages/db/a9/25282fdd24493e1022f30b7f5cdf804255c007218b2bfaa655bd7ad34b2d/simplejson-3.20.1-cp313-cp313-win_amd64.whl", hash = "sha256:1b9fd15853b90aec3b1739f4471efbf1ac05066a2c7041bf8db821bb73cd2ddc", size = 75736, upload-time = "2025-02-15T05:17:24.122Z" }, - { url = "https://files.pythonhosted.org/packages/4b/30/00f02a0a921556dd5a6db1ef2926a1bc7a8bbbfb1c49cfed68a275b8ab2b/simplejson-3.20.1-py3-none-any.whl", hash = "sha256:8a6c1bbac39fa4a79f83cbf1df6ccd8ff7069582a9fd8db1e52cea073bc2c697", size = 57121, upload-time = "2025-02-15T05:18:51.243Z" }, +version = "3.20.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/41/f4/a1ac5ed32f7ed9a088d62a59d410d4c204b3b3815722e2ccfb491fa8251b/simplejson-3.20.2.tar.gz", hash = "sha256:5fe7a6ce14d1c300d80d08695b7f7e633de6cd72c80644021874d985b3393649", size = 85784, upload-time = "2025-09-26T16:29:36.64Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b9/3e/96898c6c66d9dca3f9bd14d7487bf783b4acc77471b42f979babbb68d4ca/simplejson-3.20.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:06190b33cd7849efc413a5738d3da00b90e4a5382fd3d584c841ac20fb828c6f", size = 92633, upload-time = "2025-09-26T16:27:45.028Z" }, + { url = "https://files.pythonhosted.org/packages/6b/a2/cd2e10b880368305d89dd540685b8bdcc136df2b3c76b5ddd72596254539/simplejson-3.20.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4ad4eac7d858947a30d2c404e61f16b84d16be79eb6fb316341885bdde864fa8", size = 75309, upload-time = "2025-09-26T16:27:46.142Z" }, + { url = "https://files.pythonhosted.org/packages/5d/02/290f7282eaa6ebe945d35c47e6534348af97472446951dce0d144e013f4c/simplejson-3.20.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b392e11c6165d4a0fde41754a0e13e1d88a5ad782b245a973dd4b2bdb4e5076a", size = 75308, upload-time = "2025-09-26T16:27:47.542Z" }, + { url = "https://files.pythonhosted.org/packages/43/91/43695f17b69e70c4b0b03247aa47fb3989d338a70c4b726bbdc2da184160/simplejson-3.20.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51eccc4e353eed3c50e0ea2326173acdc05e58f0c110405920b989d481287e51", size = 143733, upload-time = "2025-09-26T16:27:48.673Z" }, + { url = "https://files.pythonhosted.org/packages/9b/4b/fdcaf444ac1c3cbf1c52bf00320c499e1cf05d373a58a3731ae627ba5e2d/simplejson-3.20.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:306e83d7c331ad833d2d43c76a67f476c4b80c4a13334f6e34bb110e6105b3bd", size = 153397, upload-time = "2025-09-26T16:27:49.89Z" }, + { url = "https://files.pythonhosted.org/packages/c4/83/21550f81a50cd03599f048a2d588ffb7f4c4d8064ae091511e8e5848eeaa/simplejson-3.20.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f820a6ac2ef0bc338ae4963f4f82ccebdb0824fe9caf6d660670c578abe01013", size = 141654, upload-time = "2025-09-26T16:27:51.168Z" }, + { url = "https://files.pythonhosted.org/packages/cf/54/d76c0e72ad02450a3e723b65b04f49001d0e73218ef6a220b158a64639cb/simplejson-3.20.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21e7a066528a5451433eb3418184f05682ea0493d14e9aae690499b7e1eb6b81", size = 144913, upload-time = "2025-09-26T16:27:52.331Z" }, + { url = "https://files.pythonhosted.org/packages/3f/49/976f59b42a6956d4aeb075ada16ad64448a985704bc69cd427a2245ce835/simplejson-3.20.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:438680ddde57ea87161a4824e8de04387b328ad51cfdf1eaf723623a3014b7aa", size = 144568, upload-time = "2025-09-26T16:27:53.41Z" }, + { url = "https://files.pythonhosted.org/packages/60/c7/30bae30424ace8cd791ca660fed454ed9479233810fe25c3f3eab3d9dc7b/simplejson-3.20.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:cac78470ae68b8d8c41b6fca97f5bf8e024ca80d5878c7724e024540f5cdaadb", size = 146239, upload-time = "2025-09-26T16:27:54.502Z" }, + { url = "https://files.pythonhosted.org/packages/79/3e/7f3b7b97351c53746e7b996fcd106986cda1954ab556fd665314756618d2/simplejson-3.20.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7524e19c2da5ef281860a3d74668050c6986be15c9dd99966034ba47c68828c2", size = 154497, upload-time = "2025-09-26T16:27:55.885Z" }, + { url = "https://files.pythonhosted.org/packages/1d/48/7241daa91d0bf19126589f6a8dcbe8287f4ed3d734e76fd4a092708947be/simplejson-3.20.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0e9b6d845a603b2eef3394eb5e21edb8626cd9ae9a8361d14e267eb969dbe413", size = 148069, upload-time = "2025-09-26T16:27:57.039Z" }, + { url = "https://files.pythonhosted.org/packages/e6/f4/ef18d2962fe53e7be5123d3784e623859eec7ed97060c9c8536c69d34836/simplejson-3.20.2-cp311-cp311-win32.whl", hash = "sha256:47d8927e5ac927fdd34c99cc617938abb3624b06ff86e8e219740a86507eb961", size = 74158, upload-time = "2025-09-26T16:27:58.265Z" }, + { url = "https://files.pythonhosted.org/packages/35/fd/3d1158ecdc573fdad81bf3cc78df04522bf3959758bba6597ba4c956c74d/simplejson-3.20.2-cp311-cp311-win_amd64.whl", hash = "sha256:ba4edf3be8e97e4713d06c3d302cba1ff5c49d16e9d24c209884ac1b8455520c", size = 75911, upload-time = "2025-09-26T16:27:59.292Z" }, + { url = "https://files.pythonhosted.org/packages/9d/9e/1a91e7614db0416885eab4136d49b7303de20528860ffdd798ce04d054db/simplejson-3.20.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:4376d5acae0d1e91e78baeba4ee3cf22fbf6509d81539d01b94e0951d28ec2b6", size = 93523, upload-time = "2025-09-26T16:28:00.356Z" }, + { url = "https://files.pythonhosted.org/packages/5e/2b/d2413f5218fc25608739e3d63fe321dfa85c5f097aa6648dbe72513a5f12/simplejson-3.20.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f8fe6de652fcddae6dec8f281cc1e77e4e8f3575249e1800090aab48f73b4259", size = 75844, upload-time = "2025-09-26T16:28:01.756Z" }, + { url = "https://files.pythonhosted.org/packages/ad/f1/efd09efcc1e26629e120fef59be059ce7841cc6e1f949a4db94f1ae8a918/simplejson-3.20.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:25ca2663d99328d51e5a138f22018e54c9162438d831e26cfc3458688616eca8", size = 75655, upload-time = "2025-09-26T16:28:03.037Z" }, + { url = "https://files.pythonhosted.org/packages/97/ec/5c6db08e42f380f005d03944be1af1a6bd501cc641175429a1cbe7fb23b9/simplejson-3.20.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12a6b2816b6cab6c3fd273d43b1948bc9acf708272074c8858f579c394f4cbc9", size = 150335, upload-time = "2025-09-26T16:28:05.027Z" }, + { url = "https://files.pythonhosted.org/packages/81/f5/808a907485876a9242ec67054da7cbebefe0ee1522ef1c0be3bfc90f96f6/simplejson-3.20.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac20dc3fcdfc7b8415bfc3d7d51beccd8695c3f4acb7f74e3a3b538e76672868", size = 158519, upload-time = "2025-09-26T16:28:06.5Z" }, + { url = "https://files.pythonhosted.org/packages/66/af/b8a158246834645ea890c36136584b0cc1c0e4b83a73b11ebd9c2a12877c/simplejson-3.20.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db0804d04564e70862ef807f3e1ace2cc212ef0e22deb1b3d6f80c45e5882c6b", size = 148571, upload-time = "2025-09-26T16:28:07.715Z" }, + { url = "https://files.pythonhosted.org/packages/20/05/ed9b2571bbf38f1a2425391f18e3ac11cb1e91482c22d644a1640dea9da7/simplejson-3.20.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:979ce23ea663895ae39106946ef3d78527822d918a136dbc77b9e2b7f006237e", size = 152367, upload-time = "2025-09-26T16:28:08.921Z" }, + { url = "https://files.pythonhosted.org/packages/81/2c/bad68b05dd43e93f77994b920505634d31ed239418eb6a88997d06599983/simplejson-3.20.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a2ba921b047bb029805726800819675249ef25d2f65fd0edb90639c5b1c3033c", size = 150205, upload-time = "2025-09-26T16:28:10.086Z" }, + { url = "https://files.pythonhosted.org/packages/69/46/90c7fc878061adafcf298ce60cecdee17a027486e9dce507e87396d68255/simplejson-3.20.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:12d3d4dc33770069b780cc8f5abef909fe4a3f071f18f55f6d896a370fd0f970", size = 151823, upload-time = "2025-09-26T16:28:11.329Z" }, + { url = "https://files.pythonhosted.org/packages/ab/27/b85b03349f825ae0f5d4f780cdde0bbccd4f06c3d8433f6a3882df887481/simplejson-3.20.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:aff032a59a201b3683a34be1169e71ddda683d9c3b43b261599c12055349251e", size = 158997, upload-time = "2025-09-26T16:28:12.917Z" }, + { url = "https://files.pythonhosted.org/packages/71/ad/d7f3c331fb930638420ac6d236db68e9f4c28dab9c03164c3cd0e7967e15/simplejson-3.20.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:30e590e133b06773f0dc9c3f82e567463df40598b660b5adf53eb1c488202544", size = 154367, upload-time = "2025-09-26T16:28:14.393Z" }, + { url = "https://files.pythonhosted.org/packages/f0/46/5c67324addd40fa2966f6e886cacbbe0407c03a500db94fb8bb40333fcdf/simplejson-3.20.2-cp312-cp312-win32.whl", hash = "sha256:8d7be7c99939cc58e7c5bcf6bb52a842a58e6c65e1e9cdd2a94b697b24cddb54", size = 74285, upload-time = "2025-09-26T16:28:15.931Z" }, + { url = "https://files.pythonhosted.org/packages/fa/c9/5cc2189f4acd3a6e30ffa9775bf09b354302dbebab713ca914d7134d0f29/simplejson-3.20.2-cp312-cp312-win_amd64.whl", hash = "sha256:2c0b4a67e75b945489052af6590e7dca0ed473ead5d0f3aad61fa584afe814ab", size = 75969, upload-time = "2025-09-26T16:28:17.017Z" }, + { url = "https://files.pythonhosted.org/packages/5e/9e/f326d43f6bf47f4e7704a4426c36e044c6bedfd24e072fb8e27589a373a5/simplejson-3.20.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:90d311ba8fcd733a3677e0be21804827226a57144130ba01c3c6a325e887dd86", size = 93530, upload-time = "2025-09-26T16:28:18.07Z" }, + { url = "https://files.pythonhosted.org/packages/35/28/5a4b8f3483fbfb68f3f460bc002cef3a5735ef30950e7c4adce9c8da15c7/simplejson-3.20.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:feed6806f614bdf7f5cb6d0123cb0c1c5f40407ef103aa935cffaa694e2e0c74", size = 75846, upload-time = "2025-09-26T16:28:19.12Z" }, + { url = "https://files.pythonhosted.org/packages/7a/4d/30dfef83b9ac48afae1cf1ab19c2867e27b8d22b5d9f8ca7ce5a0a157d8c/simplejson-3.20.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6b1d8d7c3e1a205c49e1aee6ba907dcb8ccea83651e6c3e2cb2062f1e52b0726", size = 75661, upload-time = "2025-09-26T16:28:20.219Z" }, + { url = "https://files.pythonhosted.org/packages/09/1d/171009bd35c7099d72ef6afd4bb13527bab469965c968a17d69a203d62a6/simplejson-3.20.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:552f55745044a24c3cb7ec67e54234be56d5d6d0e054f2e4cf4fb3e297429be5", size = 150579, upload-time = "2025-09-26T16:28:21.337Z" }, + { url = "https://files.pythonhosted.org/packages/61/ae/229bbcf90a702adc6bfa476e9f0a37e21d8c58e1059043038797cbe75b8c/simplejson-3.20.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2da97ac65165d66b0570c9e545786f0ac7b5de5854d3711a16cacbcaa8c472d", size = 158797, upload-time = "2025-09-26T16:28:22.53Z" }, + { url = "https://files.pythonhosted.org/packages/90/c5/fefc0ac6b86b9108e302e0af1cf57518f46da0baedd60a12170791d56959/simplejson-3.20.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f59a12966daa356bf68927fca5a67bebac0033cd18b96de9c2d426cd11756cd0", size = 148851, upload-time = "2025-09-26T16:28:23.733Z" }, + { url = "https://files.pythonhosted.org/packages/43/f1/b392952200f3393bb06fbc4dd975fc63a6843261705839355560b7264eb2/simplejson-3.20.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:133ae2098a8e162c71da97cdab1f383afdd91373b7ff5fe65169b04167da976b", size = 152598, upload-time = "2025-09-26T16:28:24.962Z" }, + { url = "https://files.pythonhosted.org/packages/f4/b4/d6b7279e52a3e9c0fa8c032ce6164e593e8d9cf390698ee981ed0864291b/simplejson-3.20.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7977640af7b7d5e6a852d26622057d428706a550f7f5083e7c4dd010a84d941f", size = 150498, upload-time = "2025-09-26T16:28:26.114Z" }, + { url = "https://files.pythonhosted.org/packages/62/22/ec2490dd859224326d10c2fac1353e8ad5c84121be4837a6dd6638ba4345/simplejson-3.20.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b530ad6d55e71fa9e93e1109cf8182f427a6355848a4ffa09f69cc44e1512522", size = 152129, upload-time = "2025-09-26T16:28:27.552Z" }, + { url = "https://files.pythonhosted.org/packages/33/ce/b60214d013e93dd9e5a705dcb2b88b6c72bada442a97f79828332217f3eb/simplejson-3.20.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:bd96a7d981bf64f0e42345584768da4435c05b24fd3c364663f5fbc8fabf82e3", size = 159359, upload-time = "2025-09-26T16:28:28.667Z" }, + { url = "https://files.pythonhosted.org/packages/99/21/603709455827cdf5b9d83abe726343f542491ca8dc6a2528eb08de0cf034/simplejson-3.20.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f28ee755fadb426ba2e464d6fcf25d3f152a05eb6b38e0b4f790352f5540c769", size = 154717, upload-time = "2025-09-26T16:28:30.288Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f9/dc7f7a4bac16cf7eb55a4df03ad93190e11826d2a8950052949d3dfc11e2/simplejson-3.20.2-cp313-cp313-win32.whl", hash = "sha256:472785b52e48e3eed9b78b95e26a256f59bb1ee38339be3075dad799e2e1e661", size = 74289, upload-time = "2025-09-26T16:28:31.809Z" }, + { url = "https://files.pythonhosted.org/packages/87/10/d42ad61230436735c68af1120622b28a782877146a83d714da7b6a2a1c4e/simplejson-3.20.2-cp313-cp313-win_amd64.whl", hash = "sha256:a1a85013eb33e4820286139540accbe2c98d2da894b2dcefd280209db508e608", size = 75972, upload-time = "2025-09-26T16:28:32.883Z" }, + { url = "https://files.pythonhosted.org/packages/05/5b/83e1ff87eb60ca706972f7e02e15c0b33396e7bdbd080069a5d1b53cf0d8/simplejson-3.20.2-py3-none-any.whl", hash = "sha256:3b6bb7fb96efd673eac2e4235200bfffdc2353ad12c54117e1e4e2fc485ac017", size = 57309, upload-time = "2025-09-26T16:29:35.312Z" }, ] [[package]] @@ -3391,11 +3412,11 @@ dependencies = [ [[package]] name = "trove-classifiers" -version = "2025.9.9.12" +version = "2025.9.11.17" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/db/52/45fa9c4f39ada33d803e4c0f288e94dc2e9d499201a0aa5697e30ef8a0cb/trove_classifiers-2025.9.9.12.tar.gz", hash = "sha256:6a00942fc023f4f383af3254b4ed818d7fa7923a3c7c03b0e71da2ce71b538ab", size = 16970, upload-time = "2025-09-09T12:23:47.737Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/9a/778622bc06632529817c3c524c82749a112603ae2bbcf72ee3eb33a2c4f1/trove_classifiers-2025.9.11.17.tar.gz", hash = "sha256:931ca9841a5e9c9408bc2ae67b50d28acf85bef56219b56860876dd1f2d024dd", size = 16975, upload-time = "2025-09-11T17:07:50.97Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/15/05/618f6a55cced5402364af0d7629cbfd04e9852d464193bde9bd03c85b56a/trove_classifiers-2025.9.9.12-py3-none-any.whl", hash = "sha256:d449bd9d4715105657732d6dd1f46aa1595278d01ef1716ca164b35867135a4f", size = 14136, upload-time = "2025-09-09T12:23:46.314Z" }, + { url = "https://files.pythonhosted.org/packages/e1/85/a4ff8758c66f1fc32aa5e9a145908394bf9cf1c79ffd1113cfdeb77e74e4/trove_classifiers-2025.9.11.17-py3-none-any.whl", hash = "sha256:5d392f2d244deb1866556457d6f3516792124a23d1c3a463a2e8668a5d1c15dd", size = 14158, upload-time = "2025-09-11T17:07:49.886Z" }, ] [[package]] @@ -3436,14 +3457,14 @@ wheels = [ [[package]] name = "typing-inspection" -version = "0.4.1" +version = "0.4.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f8/b1/0c11f5058406b3af7609f121aaa6b609744687f1d158b3c3a5bf4cc94238/typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28", size = 75726, upload-time = "2025-05-21T18:55:23.885Z" } +sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51", size = 14552, upload-time = "2025-05-21T18:55:22.152Z" }, + { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, ] [[package]] @@ -3506,11 +3527,11 @@ wheels = [ [[package]] name = "wcwidth" -version = "0.2.13" +version = "0.2.14" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6c/63/53559446a878410fc5a5974feb13d31d78d752eb18aeba59c7fef1af7598/wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5", size = 101301, upload-time = "2024-01-06T02:10:57.829Z" } +sdist = { url = "https://files.pythonhosted.org/packages/24/30/6b0809f4510673dc723187aeaf24c7f5459922d01e2f794277a3dfb90345/wcwidth-0.2.14.tar.gz", hash = "sha256:4d478375d31bc5395a3c55c40ccdf3354688364cd61c4f6adacaa9215d0b3605", size = 102293, upload-time = "2025-09-22T16:29:53.023Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", size = 34166, upload-time = "2024-01-06T02:10:55.763Z" }, + { url = "https://files.pythonhosted.org/packages/af/b5/123f13c975e9f27ab9c0770f514345bd406d0e8d3b7a0723af9d43f710af/wcwidth-0.2.14-py2.py3-none-any.whl", hash = "sha256:a7bb560c8aee30f9957e5f9895805edd20602f2d7f720186dfd906e82b4982e1", size = 37286, upload-time = "2025-09-22T16:29:51.641Z" }, ] [[package]] @@ -3549,6 +3570,45 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e1/07/c6fe3ad3e685340704d314d765b7912993bcb8dc198f0e7a89382d37974b/win32_setctime-1.2.0-py3-none-any.whl", hash = "sha256:95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390", size = 4083, upload-time = "2024-12-07T15:28:26.465Z" }, ] +[[package]] +name = "wrapt" +version = "1.17.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/95/8f/aeb76c5b46e273670962298c23e7ddde79916cb74db802131d49a85e4b7d/wrapt-1.17.3.tar.gz", hash = "sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0", size = 55547, upload-time = "2025-08-12T05:53:21.714Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/52/db/00e2a219213856074a213503fdac0511203dceefff26e1daa15250cc01a0/wrapt-1.17.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7", size = 53482, upload-time = "2025-08-12T05:51:45.79Z" }, + { url = "https://files.pythonhosted.org/packages/5e/30/ca3c4a5eba478408572096fe9ce36e6e915994dd26a4e9e98b4f729c06d9/wrapt-1.17.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85", size = 38674, upload-time = "2025-08-12T05:51:34.629Z" }, + { url = "https://files.pythonhosted.org/packages/31/25/3e8cc2c46b5329c5957cec959cb76a10718e1a513309c31399a4dad07eb3/wrapt-1.17.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f", size = 38959, upload-time = "2025-08-12T05:51:56.074Z" }, + { url = "https://files.pythonhosted.org/packages/5d/8f/a32a99fc03e4b37e31b57cb9cefc65050ea08147a8ce12f288616b05ef54/wrapt-1.17.3-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b32888aad8b6e68f83a8fdccbf3165f5469702a7544472bdf41f582970ed3311", size = 82376, upload-time = "2025-08-12T05:52:32.134Z" }, + { url = "https://files.pythonhosted.org/packages/31/57/4930cb8d9d70d59c27ee1332a318c20291749b4fba31f113c2f8ac49a72e/wrapt-1.17.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cccf4f81371f257440c88faed6b74f1053eef90807b77e31ca057b2db74edb1", size = 83604, upload-time = "2025-08-12T05:52:11.663Z" }, + { url = "https://files.pythonhosted.org/packages/a8/f3/1afd48de81d63dd66e01b263a6fbb86e1b5053b419b9b33d13e1f6d0f7d0/wrapt-1.17.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8a210b158a34164de8bb68b0e7780041a903d7b00c87e906fb69928bf7890d5", size = 82782, upload-time = "2025-08-12T05:52:12.626Z" }, + { url = "https://files.pythonhosted.org/packages/1e/d7/4ad5327612173b144998232f98a85bb24b60c352afb73bc48e3e0d2bdc4e/wrapt-1.17.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:79573c24a46ce11aab457b472efd8d125e5a51da2d1d24387666cd85f54c05b2", size = 82076, upload-time = "2025-08-12T05:52:33.168Z" }, + { url = "https://files.pythonhosted.org/packages/bb/59/e0adfc831674a65694f18ea6dc821f9fcb9ec82c2ce7e3d73a88ba2e8718/wrapt-1.17.3-cp311-cp311-win32.whl", hash = "sha256:c31eebe420a9a5d2887b13000b043ff6ca27c452a9a22fa71f35f118e8d4bf89", size = 36457, upload-time = "2025-08-12T05:53:03.936Z" }, + { url = "https://files.pythonhosted.org/packages/83/88/16b7231ba49861b6f75fc309b11012ede4d6b0a9c90969d9e0db8d991aeb/wrapt-1.17.3-cp311-cp311-win_amd64.whl", hash = "sha256:0b1831115c97f0663cb77aa27d381237e73ad4f721391a9bfb2fe8bc25fa6e77", size = 38745, upload-time = "2025-08-12T05:53:02.885Z" }, + { url = "https://files.pythonhosted.org/packages/9a/1e/c4d4f3398ec073012c51d1c8d87f715f56765444e1a4b11e5180577b7e6e/wrapt-1.17.3-cp311-cp311-win_arm64.whl", hash = "sha256:5a7b3c1ee8265eb4c8f1b7d29943f195c00673f5ab60c192eba2d4a7eae5f46a", size = 36806, upload-time = "2025-08-12T05:52:53.368Z" }, + { url = "https://files.pythonhosted.org/packages/9f/41/cad1aba93e752f1f9268c77270da3c469883d56e2798e7df6240dcb2287b/wrapt-1.17.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0", size = 53998, upload-time = "2025-08-12T05:51:47.138Z" }, + { url = "https://files.pythonhosted.org/packages/60/f8/096a7cc13097a1869fe44efe68dace40d2a16ecb853141394047f0780b96/wrapt-1.17.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba", size = 39020, upload-time = "2025-08-12T05:51:35.906Z" }, + { url = "https://files.pythonhosted.org/packages/33/df/bdf864b8997aab4febb96a9ae5c124f700a5abd9b5e13d2a3214ec4be705/wrapt-1.17.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd", size = 39098, upload-time = "2025-08-12T05:51:57.474Z" }, + { url = "https://files.pythonhosted.org/packages/9f/81/5d931d78d0eb732b95dc3ddaeeb71c8bb572fb01356e9133916cd729ecdd/wrapt-1.17.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828", size = 88036, upload-time = "2025-08-12T05:52:34.784Z" }, + { url = "https://files.pythonhosted.org/packages/ca/38/2e1785df03b3d72d34fc6252d91d9d12dc27a5c89caef3335a1bbb8908ca/wrapt-1.17.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9", size = 88156, upload-time = "2025-08-12T05:52:13.599Z" }, + { url = "https://files.pythonhosted.org/packages/b3/8b/48cdb60fe0603e34e05cffda0b2a4adab81fd43718e11111a4b0100fd7c1/wrapt-1.17.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396", size = 87102, upload-time = "2025-08-12T05:52:14.56Z" }, + { url = "https://files.pythonhosted.org/packages/3c/51/d81abca783b58f40a154f1b2c56db1d2d9e0d04fa2d4224e357529f57a57/wrapt-1.17.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc", size = 87732, upload-time = "2025-08-12T05:52:36.165Z" }, + { url = "https://files.pythonhosted.org/packages/9e/b1/43b286ca1392a006d5336412d41663eeef1ad57485f3e52c767376ba7e5a/wrapt-1.17.3-cp312-cp312-win32.whl", hash = "sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe", size = 36705, upload-time = "2025-08-12T05:53:07.123Z" }, + { url = "https://files.pythonhosted.org/packages/28/de/49493f962bd3c586ab4b88066e967aa2e0703d6ef2c43aa28cb83bf7b507/wrapt-1.17.3-cp312-cp312-win_amd64.whl", hash = "sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c", size = 38877, upload-time = "2025-08-12T05:53:05.436Z" }, + { url = "https://files.pythonhosted.org/packages/f1/48/0f7102fe9cb1e8a5a77f80d4f0956d62d97034bbe88d33e94699f99d181d/wrapt-1.17.3-cp312-cp312-win_arm64.whl", hash = "sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6", size = 36885, upload-time = "2025-08-12T05:52:54.367Z" }, + { url = "https://files.pythonhosted.org/packages/fc/f6/759ece88472157acb55fc195e5b116e06730f1b651b5b314c66291729193/wrapt-1.17.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a47681378a0439215912ef542c45a783484d4dd82bac412b71e59cf9c0e1cea0", size = 54003, upload-time = "2025-08-12T05:51:48.627Z" }, + { url = "https://files.pythonhosted.org/packages/4f/a9/49940b9dc6d47027dc850c116d79b4155f15c08547d04db0f07121499347/wrapt-1.17.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:54a30837587c6ee3cd1a4d1c2ec5d24e77984d44e2f34547e2323ddb4e22eb77", size = 39025, upload-time = "2025-08-12T05:51:37.156Z" }, + { url = "https://files.pythonhosted.org/packages/45/35/6a08de0f2c96dcdd7fe464d7420ddb9a7655a6561150e5fc4da9356aeaab/wrapt-1.17.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:16ecf15d6af39246fe33e507105d67e4b81d8f8d2c6598ff7e3ca1b8a37213f7", size = 39108, upload-time = "2025-08-12T05:51:58.425Z" }, + { url = "https://files.pythonhosted.org/packages/0c/37/6faf15cfa41bf1f3dba80cd3f5ccc6622dfccb660ab26ed79f0178c7497f/wrapt-1.17.3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6fd1ad24dc235e4ab88cda009e19bf347aabb975e44fd5c2fb22a3f6e4141277", size = 88072, upload-time = "2025-08-12T05:52:37.53Z" }, + { url = "https://files.pythonhosted.org/packages/78/f2/efe19ada4a38e4e15b6dff39c3e3f3f73f5decf901f66e6f72fe79623a06/wrapt-1.17.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ed61b7c2d49cee3c027372df5809a59d60cf1b6c2f81ee980a091f3afed6a2d", size = 88214, upload-time = "2025-08-12T05:52:15.886Z" }, + { url = "https://files.pythonhosted.org/packages/40/90/ca86701e9de1622b16e09689fc24b76f69b06bb0150990f6f4e8b0eeb576/wrapt-1.17.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:423ed5420ad5f5529db9ce89eac09c8a2f97da18eb1c870237e84c5a5c2d60aa", size = 87105, upload-time = "2025-08-12T05:52:17.914Z" }, + { url = "https://files.pythonhosted.org/packages/fd/e0/d10bd257c9a3e15cbf5523025252cc14d77468e8ed644aafb2d6f54cb95d/wrapt-1.17.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e01375f275f010fcbf7f643b4279896d04e571889b8a5b3f848423d91bf07050", size = 87766, upload-time = "2025-08-12T05:52:39.243Z" }, + { url = "https://files.pythonhosted.org/packages/e8/cf/7d848740203c7b4b27eb55dbfede11aca974a51c3d894f6cc4b865f42f58/wrapt-1.17.3-cp313-cp313-win32.whl", hash = "sha256:53e5e39ff71b3fc484df8a522c933ea2b7cdd0d5d15ae82e5b23fde87d44cbd8", size = 36711, upload-time = "2025-08-12T05:53:10.074Z" }, + { url = "https://files.pythonhosted.org/packages/57/54/35a84d0a4d23ea675994104e667ceff49227ce473ba6a59ba2c84f250b74/wrapt-1.17.3-cp313-cp313-win_amd64.whl", hash = "sha256:1f0b2f40cf341ee8cc1a97d51ff50dddb9fcc73241b9143ec74b30fc4f44f6cb", size = 38885, upload-time = "2025-08-12T05:53:08.695Z" }, + { url = "https://files.pythonhosted.org/packages/01/77/66e54407c59d7b02a3c4e0af3783168fff8e5d61def52cda8728439d86bc/wrapt-1.17.3-cp313-cp313-win_arm64.whl", hash = "sha256:7425ac3c54430f5fc5e7b6f41d41e704db073309acfc09305816bc6a0b26bb16", size = 36896, upload-time = "2025-08-12T05:52:55.34Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f6/a933bd70f98e9cf3e08167fc5cd7aaaca49147e48411c0bd5ae701bb2194/wrapt-1.17.3-py3-none-any.whl", hash = "sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22", size = 23591, upload-time = "2025-08-12T05:53:20.674Z" }, +] + [[package]] name = "xlrd" version = "2.0.2" @@ -3560,7 +3620,7 @@ wheels = [ [[package]] name = "zarr" -version = "3.1.2" +version = "3.1.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "donfig" }, @@ -3569,16 +3629,7 @@ dependencies = [ { name = "packaging" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/09/04/76261cf5bd065648b7981b41ba1936b8bd9565f80f69534e3cdf2d772ad9/zarr-3.1.2.tar.gz", hash = "sha256:688e4eb79045c110128cd16f301f2f58fa19507b1803dcbea0ea894e66e06274", size = 324221, upload-time = "2025-08-25T15:32:31.153Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/a3/d3d4fd394a10b1256f9dccb2fe0ddd125fc575d7c437b1c70df050f14176/zarr-3.1.2-py3-none-any.whl", hash = "sha256:c3e180f53ee0ef91b86f7feff6f9dd381ddd1b512d1a46580530966a493387b6", size = 261041, upload-time = "2025-08-25T15:32:29.522Z" }, -] - -[[package]] -name = "zipp" -version = "3.23.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e3/02/0f2892c661036d50ede074e376733dca2ae7c6eb617489437771209d4180/zipp-3.23.0.tar.gz", hash = "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166", size = 25547, upload-time = "2025-06-08T17:06:39.4Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/67/14be68a7bad15eecda09b1e81fca2420f7533645fe187bf4d6104c1aad52/zarr-3.1.3.tar.gz", hash = "sha256:01342f3e26a02ed5670db608a5576fbdb8d76acb5c280bd2d0082454b1ba6f79", size = 349125, upload-time = "2025-09-18T19:32:41.688Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2e/54/647ade08bf0db230bfea292f893923872fd20be6ac6f53b2b936ba839d75/zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e", size = 10276, upload-time = "2025-06-08T17:06:38.034Z" }, + { url = "https://files.pythonhosted.org/packages/1a/71/9de7229515a53d1cc5705ca9c411530f711a2242f962214d9dbfe2741aa4/zarr-3.1.3-py3-none-any.whl", hash = "sha256:45f67f87f65f14fa453f99dd8110a5936b7ac69f3a21981d33e90407c80c302a", size = 276427, upload-time = "2025-09-18T19:32:40.042Z" }, ] From 5be0a8a166416a01cb43e02b1d0a50bf0f08bb21 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Mon, 6 Oct 2025 16:01:02 -0500 Subject: [PATCH 260/265] fix: uv lock dependencies Signed-off-by: Josh Loecker --- uv.lock | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/uv.lock b/uv.lock index bcf16419..4fcb4c61 100644 --- a/uv.lock +++ b/uv.lock @@ -363,7 +363,7 @@ dependencies = [ [[package]] name = "cobra" version = "0.29.1" -source = { git = "https://github.com/ripaul/cobrapy?rev=hopsy-backend#c1790271e898071a1ebb9fda44e6032fbf982478" } +source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "appdirs" }, { name = "depinfo" }, @@ -380,6 +380,10 @@ dependencies = [ { name = "ruamel-yaml" }, { name = "swiglpk" }, ] +sdist = { url = "https://files.pythonhosted.org/packages/12/21/f84b7f78990c80ef06aaae5318159e2341fb74fd3cd8e83d69ab01515f06/cobra-0.29.1.tar.gz", hash = "sha256:47cd4fe80eb329ed75ccfb7ecbaac6275e986685392d52922bc8ad3cbc599674", size = 1164782, upload-time = "2024-09-19T12:46:30.766Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/5c/f586d381e8307c2c46d4b382c23f50f3ee023e3d811cb0e7ae30b364088a/cobra-0.29.1-py2.py3-none-any.whl", hash = "sha256:734df889e751171c12ee9c5ec6f2567f47f9997e183822d4290776aa650c9593", size = 1192190, upload-time = "2024-09-19T12:46:28.305Z" }, +] [[package]] name = "colorama" @@ -482,7 +486,7 @@ requires-dist = [ { name = "aioftp", specifier = ">=0.23.1" }, { name = "anndata", specifier = ">=0.12.0" }, { name = "cobamp", git = "https://github.com/JoshLoecker/cobamp?rev=master" }, - { name = "cobra", git = "https://github.com/ripaul/cobrapy?rev=hopsy-backend" }, + { name = "cobra", specifier = ">=0.28.0" }, { name = "commitizen", marker = "extra == 'dev'", specifier = ">=4.8.3" }, { name = "commitlint", marker = "extra == 'dev'", specifier = ">=1.3.1" }, { name = "fast-bioservices", specifier = ">=0.3.9" }, From 50d85b8e9c851d0f7bb90c29746ac1e8cab8ad14 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Mon, 6 Oct 2025 16:01:37 -0500 Subject: [PATCH 261/265] fix: remove `--cov` for coverage updating Signed-off-by: Josh Loecker --- .github/workflows/continuous_integration.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/continuous_integration.yml b/.github/workflows/continuous_integration.yml index 286f54d0..dfd9b1a4 100644 --- a/.github/workflows/continuous_integration.yml +++ b/.github/workflows/continuous_integration.yml @@ -27,7 +27,7 @@ jobs: run: uv sync --python "${{ matrix.python-version }}" --all-extras --dev - name: Run tests - run: uv run --python "${{ matrix.python-version }}" pytest --cov --junitxml=junit.xml -o junit_family=legacy + run: uv run --python "${{ matrix.python-version }}" pytest - name: Cache Clear run: uv cache prune --ci From 11ac5c2bce097e0d3cfaebeb06571d380881f7b7 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Mon, 6 Oct 2025 16:07:17 -0500 Subject: [PATCH 262/265] fix: remove duplicate code from merge conflict Signed-off-by: Josh Loecker --- main/como/rnaseq_preprocess.py | 4 +- main/como/utils.py | 126 +++------------------------------ 2 files changed, 10 insertions(+), 120 deletions(-) diff --git a/main/como/rnaseq_preprocess.py b/main/como/rnaseq_preprocess.py index c17355dd..b83678d1 100644 --- a/main/como/rnaseq_preprocess.py +++ b/main/como/rnaseq_preprocess.py @@ -5,7 +5,7 @@ import re import sys from dataclasses import asdict, dataclass, field -from io import StringIO, TextIOWrapper +from io import TextIOWrapper from itertools import chain from pathlib import Path from typing import Final, Literal, cast @@ -62,7 +62,7 @@ async def build_from_tab(cls, filepath: Path) -> _STARinformation: num_ambiguous = [int(i) for i in ambiguous.removesuffix("\n").split("\t")[1:]] df = await _read_file( - filepath, + path=filepath, sep="\t", header=None, skiprows=4, diff --git a/main/como/utils.py b/main/como/utils.py index ab9cc406..ececc902 100644 --- a/main/como/utils.py +++ b/main/como/utils.py @@ -1,13 +1,11 @@ from __future__ import annotations -import asyncio import contextlib import io import sys -import typing from collections.abc import Iterator from pathlib import Path -from typing import TextIO, TypeVar, cast, overload +from typing import Literal, NoReturn, TextIO, TypeVar, cast, overload import aiofiles import numpy.typing as npt @@ -87,7 +85,7 @@ def split_gene_expression_data( if recon_algorithm in {Algorithm.IMAT, Algorithm.TINIT}: expression_data.rename(columns={"combine_z": "active"}, inplace=True) - expression_data = expression_data[[identifier_column, "active"]] + expression_data = cast(typ=pd.DataFrame, val=expression_data[[identifier_column, "active"]]) single_gene_names = expression_data[~expression_data[identifier_column].astype(str).str.contains("//")] multiple_gene_names = expression_data[expression_data[identifier_column].astype(str).str.contains("//")] split_gene_names = multiple_gene_names.assign(ensembl_gene_id=multiple_gene_names[identifier_column].astype(str).str.split("///")).explode( @@ -134,60 +132,6 @@ async def _format_determination( coercion.columns = pd.Index(["input_value", *[o.value.replace(" ", "_").lower() for o in requested_output]]) return coercion -async def _read_file( - path: Path | io.StringIO | None, - h5ad_as_df: bool = True, - **kwargs, -) -> pd.DataFrame | sc.AnnData | None: - """Asynchronously read a filepath and return a pandas DataFrame. - - If the provided path is None, None will also be returned. - None may be provided to this function so that `asyncio.gather` can safely be used on all sources - (trna, mrna, scrna, proteomics) without needing to check if the user has provided those sources - - Args: - path: The path to read from - h5ad_as_df: If True and the file is an h5ad, return a DataFrame of the .X matrix instead of an AnnData object - kwargs: Additional arguments to pass to pandas.read_csv, pandas.read_excel, or scanpy.read_h5ad, depending on the filepath provided - - Returns: - None, or a pandas DataFrame or AnnData - """ - if isinstance(path, (pd.DataFrame, sc.AnnData)): - return path - if not path: - return None - - if isinstance(path, Path) and not path.exists(): - _log_and_raise_error(f"File {path} does not exist", error=FileNotFoundError, level=LogLevel.CRITICAL) - - # StringIO is used if a CSV file is read using open() directly - if isinstance(path, io.StringIO): - return pd.read_csv(path, **kwargs) - - match path.suffix: - case ".csv" | ".tsv" | ".txt" | ".tab": - if "sep" not in kwargs: - kwargs.setdefault("sep", "," if path.suffix == ".csv" else "\t") - return await asyncio.to_thread(pd.read_csv, path, **kwargs) - case ".xlsx" | ".xls": - return await asyncio.to_thread(pd.read_excel, path, **kwargs) - case ".h5ad": - adata: sc.AnnData = await asyncio.to_thread(sc.read_h5ad, path, **kwargs) - if h5ad_as_df: - df = adata.to_df().T - df.index.name = "gene_symbol" - df.reset_index(inplace=True, drop=False) - return df - return adata - case _: - _log_and_raise_error( - f"Unknown file extension '{path.suffix}'. Valid options are '.tsv', '.csv', '.xlsx', '.xls', or '.h5ad'", - error=ValueError, - level=LogLevel.CRITICAL, - ) - return None - async def get_missing_gene_data(values: list[str] | pd.DataFrame, taxon_id: int | str | Taxon) -> pd.DataFrame: if isinstance(values, list): @@ -225,9 +169,11 @@ async def _read_file(path: pd.DataFrame, h5ad_as_df: bool, **kwargs) -> pd.DataF @overload async def _read_file(path: sc.AnnData, h5ad_as_df: bool = False, **kwargs) -> sc.AnnData: ... + def _num_rows(item: pd.DataFrame | npt.NDArray) -> int: return item.shape[0] + @overload async def _read_file(path: sc.AnnData, h5ad_as_df: bool = True, **kwargs) -> pd.DataFrame: ... @@ -265,7 +211,7 @@ async def _read_file( _log_and_raise_error(f"File {path} does not exist", error=FileNotFoundError, level=LogLevel.CRITICAL) match path.suffix: - case ".csv" | ".tsv" | ".txt": + case ".csv" | ".tsv" | ".txt" | ".tab": kwargs.setdefault("sep", "," if path.suffix == ".csv" else "\t") # set sep if not defined async with aiofiles.open(path) as i_stream: content = await i_stream.read() @@ -288,31 +234,6 @@ async def _read_file( ) -async def get_missing_gene_data(values: list[str] | pd.DataFrame, taxon_id: int | str | Taxon) -> pd.DataFrame: - if isinstance(values, list): - gene_type = await determine_gene_type(values) - if all(v == "gene_symbol" for v in gene_type.values()): - return await gene_symbol_to_ensembl_and_gene_id(values, taxon=taxon_id) - elif all(v == "ensembl_gene_id" for v in gene_type.values()): - return await ensembl_to_gene_id_and_symbol(ids=values, taxon=taxon_id) - elif all(v == "entrez_gene_id" for v in gene_type.values()): - return await gene_id_to_ensembl_and_gene_symbol(ids=values, taxon=taxon_id) - else: - logger.critical("Gene data must be of the same type (i.e., all Ensembl, Entrez, or Gene Symbols)") - raise ValueError("Gene data must be of the same type (i.e., all Ensembl, Entrez, or Gene Symbols)") - else: - values: pd.DataFrame # Re-define type to assist in type hinting - if "gene_symbol" in values: - return await get_missing_gene_data(values["gene_symbol"].tolist(), taxon_id=taxon_id) - elif "entrez_gene_id" in values: - return await get_missing_gene_data(values["entrez_gene_id"].tolist(), taxon_id=taxon_id) - elif "ensembl_gene_id" in values: - return await get_missing_gene_data(values["ensembl_gene_id"].tolist(), taxon_id=taxon_id) - else: - logger.critical("Unable to find 'gene_symbol', 'entrez_gene_id', or 'ensembl_gene_id' in the input matrix.") - raise ValueError("Unable to find 'gene_symbol', 'entrez_gene_id', or 'ensembl_gene_id' in the input matrix.") - - @overload def _listify(value: list[T]) -> list[T]: ... @@ -365,45 +286,14 @@ def _log_and_raise_error( *, error: type[BaseException], level: LogLevel, -) -> typing.NoReturn: +) -> NoReturn: caller = logger.opt(depth=1) match level: case LogLevel.ERROR: caller.error(message) + raise error(message) case LogLevel.CRITICAL: caller.critical(message) + raise error(message) case _: raise ValueError(f"When raising an error, LogLevel.ERROR or LogLevel.CRITICAL must be used. Got: {level}") - -def return_placeholder_data() -> pd.DataFrame: - return pd.DataFrame(data=0, index=pd.Index(data=[0], name="entrez_gene_id"), columns=["expressed", "top"]) - - -def _set_up_logging( - level: LogLevel | str, - location: str | TextIOWrapper, - formatting: str = LOG_FORMAT, -): - if isinstance(level, str): - level = LogLevel[level.upper()] - with contextlib.suppress(ValueError): - logger.remove(0) - logger.add(sink=location, level=level.value, format=formatting) - - -def _log_and_raise_error( - message: str, - *, - error: type[BaseException], - level: LogLevel, -) -> None: - caller = logger.opt(depth=1) - match level: - case LogLevel.ERROR: - caller.error(message) - case LogLevel.CRITICAL: - caller.critical(message) - case _: - raise ValueError(f"When raising an error, LogLevel.ERROR or LogLevel.CRITICAL must be used. Got: {level}") - - raise error(message) From cb8153a9d3f51821941db76d1685ad1d6c20d1a3 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Mon, 6 Oct 2025 14:31:39 -0500 Subject: [PATCH 263/265] Move ref models (#232) --- .../GeneralModelUpdatedV2.mat | Bin main/data/{ => reference_models}/iMM_madrid.mat | Bin 2 files changed, 0 insertions(+), 0 deletions(-) rename main/data/{ => reference_models}/GeneralModelUpdatedV2.mat (100%) rename main/data/{ => reference_models}/iMM_madrid.mat (100%) diff --git a/main/data/GeneralModelUpdatedV2.mat b/main/data/reference_models/GeneralModelUpdatedV2.mat similarity index 100% rename from main/data/GeneralModelUpdatedV2.mat rename to main/data/reference_models/GeneralModelUpdatedV2.mat diff --git a/main/data/iMM_madrid.mat b/main/data/reference_models/iMM_madrid.mat similarity index 100% rename from main/data/iMM_madrid.mat rename to main/data/reference_models/iMM_madrid.mat From d688e0d29388a8ba5b7f053ddc5864e8661ffc2b Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 7 Oct 2025 09:41:40 -0500 Subject: [PATCH 264/265] chore: add V3 reference model from utils-update Signed-off-by: Josh Loecker --- .../GeneralModelUpdatedV3.mat | Bin 0 -> 13790656 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 main/data/reference_models/GeneralModelUpdatedV3.mat diff --git a/main/data/reference_models/GeneralModelUpdatedV3.mat b/main/data/reference_models/GeneralModelUpdatedV3.mat new file mode 100644 index 0000000000000000000000000000000000000000..f10c01e1e889ff317921a3fb55fc3b552d759442 GIT binary patch literal 13790656 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
py9IdtkD?5T|)#<}ki<79tKf)91&wF?u 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

3-usB=DFY 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

Bqy+D@L$uoxGWCEUGl6ie*@=ojQ`E8mwHbm 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¬yU+9eI6mjW%;!9>0oa`Rf1Cvd#WYhb_lZv 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

1{=N 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ʿs+8 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%0Dw>7-qq&m>qLq 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 z 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

AKO+n0p8 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 literal 0 HcmV?d00001 From 50e19d2cdbadbce508ddb09a7159f307fd9a6675 Mon Sep 17 00:00:00 2001 From: Josh Loecker Date: Tue, 7 Oct 2025 09:52:23 -0500 Subject: [PATCH 265/265] fix: typo for expected test value Signed-off-by: Josh Loecker --- tests/unit/test_fisher_stats.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/test_fisher_stats.py b/tests/unit/test_fisher_stats.py index 34140eb7..f607a931 100644 --- a/tests/unit/test_fisher_stats.py +++ b/tests/unit/test_fisher_stats.py @@ -13,4 +13,4 @@ def test_fisher_stats(): assert real.a == 32 assert real.b == 10 assert real.c == 4496 - assert real.d == 6082 + assert real.d == 6072