diff --git a/.env-template b/.env-template index b740cfa7..a5efdff1 100644 --- a/.env-template +++ b/.env-template @@ -1,2 +1,11 @@ # Copy from the "S118"-subscription in the Azure Portal. (lcm-dev/lcmdevstorage/Access keys) -TABLE_KEY= \ No newline at end of file +TABLE_KEY= +APPINSIGHTS_CON_STRING= + +# Set this when running Vite behind a reverse proxy (e.g. nginx on port 80). +# Tells the browser which port to use for HMR websocket connections. +# HMR_CLIENT_PORT=80 + +# Enable filesystem polling for Vite HMR. +# Required on Windows (WSL2 mounted filesystems don't emit native file events). +# USE_POLLING=true diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml deleted file mode 100644 index a96d395c..00000000 --- a/.github/workflows/codeql-analysis.yml +++ /dev/null @@ -1,72 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -name: "CodeQL" - -on: - workflow_dispatch: - push: - branches: [master] - pull_request: - # The branches below must be a subset of the branches above - branches: [master] - schedule: - - cron: '0 7 * * 1' - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - # Override automatic language detection by changing the below list - # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'] - language: ['javascript', 'python'] - # Learn more... - # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - # We must fetch at least the immediate parents so that if this is - # a pull request then we can checkout the head. - fetch-depth: 2 - - # If this run was triggered by a pull request event, then checkout - # the head of the pull request instead of the merge commit. - - run: git checkout HEAD^2 - if: ${{ github.event_name == 'pull_request' }} - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main - - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v2 - - # ℹ️ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl - - # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language - - #- run: | - # make bootstrap - # make release - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 diff --git a/.github/workflows/on-pull-request.yaml b/.github/workflows/on-pull-request.yaml new file mode 100644 index 00000000..84899c03 --- /dev/null +++ b/.github/workflows/on-pull-request.yaml @@ -0,0 +1,12 @@ +name: "On PR updated" +on: + workflow_dispatch: + pull_request: + types: [opened, synchronize, reopened] + +permissions: + contents: read + +jobs: + tests: + uses: ./.github/workflows/tests.yaml diff --git a/.github/workflows/on-push-prod.yaml b/.github/workflows/on-push-master-branch.yaml similarity index 52% rename from .github/workflows/on-push-prod.yaml rename to .github/workflows/on-push-master-branch.yaml index bbacc935..1196ba84 100644 --- a/.github/workflows/on-push-prod.yaml +++ b/.github/workflows/on-push-master-branch.yaml @@ -1,22 +1,28 @@ -name: Algorithm-Report - +name: "Push to master branch" on: workflow_dispatch: push: branches: - - prod + - master + +permissions: + contents: read + actions: write jobs: - test-report: + tests: + uses: ./.github/workflows/tests.yaml + + build-test-report: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: "Create report" run: docker compose build api && docker compose run -u 0 api python src/tests/optimizer_test.py - name: Archive results - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: algorithm-report - path: api/test_report.png + path: api/src/test_report.png diff --git a/.github/workflows/on-push.yaml b/.github/workflows/tests.yaml similarity index 68% rename from .github/workflows/on-push.yaml rename to .github/workflows/tests.yaml index 5b54e643..897bf731 100644 --- a/.github/workflows/on-push.yaml +++ b/.github/workflows/tests.yaml @@ -1,25 +1,30 @@ -name: CI - -on: +name: "Test" +on: workflow_dispatch: + workflow_call: push: + branches: + - master + +permissions: + contents: read jobs: test-api: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: "Build API test image" run: docker build --tag api-development ./api - name: "API UnitTests" - run: docker run --rm -e TABEL_KEY="${{ secrets.TABEL_KEY }}" api-development pytest src/tests + run: docker run --rm api-development pytest src/tests test-web: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: "Build web" run: docker build --tag web-development ./web @@ -27,10 +32,10 @@ jobs: pre-commit: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.12' cache: 'pip' diff --git a/.gitignore b/.gitignore index 559a5826..286a2e61 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,6 @@ api/src/tests/products_data.py /api/test_report.png /api/.coverage /api/src/test_data/interpolate_input.csv -.python-version \ No newline at end of file +.python-version +secrets/ +!secrets/.gitkeep diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d9b8768d..497fddc1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,34 +1,32 @@ repos: -- repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 - hooks: - - id: check-ast - language_version: python3.12 - - id: check-merge-conflict - - id: check-json - - id: check-yaml + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 + hooks: + - id: check-ast + - id: check-merge-conflict + - id: check-json + - id: check-yaml + exclude: (mkdocs\.ya?ml|catalog-info\.yaml)$ + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: "v0.15.4" + hooks: + - id: ruff-format + name: Code formatting + files: ^api/.*\.py$ -- repo: https://github.com/astral-sh/ruff-pre-commit - rev: 'v0.9.7' - hooks: - - id: ruff-format - name: Code formatting - files: ^api/.*\.py$ + - id: ruff + name: Code linting + files: ^api/.*\.py$ + args: + - --fix + - --unsafe-fixes - - id: ruff - name: Code linting - files: ^api/.*\.py$ - args: - - --fix - - --unsafe-fixes - - -- repo: https://github.com/biomejs/pre-commit - rev: "v0.6.1" - hooks: - - id: biome-check - name: "Lint: biome (js/ts)" - files: ^web/.*\.(ts|tsx|js|css|html|json)$ - additional_dependencies: ["@biomejs/biome@1.9.4"] - args: ["--config-path", "web"] + - repo: https://github.com/biomejs/pre-commit + rev: "v2.4.4" + hooks: + - id: biome-check + name: "Lint: biome (js/ts)" + files: ^web/.*\.(ts|tsx|js|css|html|json)$ + additional_dependencies: ["@biomejs/biome@2.4.4"] + args: ["--config-path", "."] diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..0de01264 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,12 @@ +{ + "python.analysis.autoImportCompletions": true, + "python.analysis.indexing": true, + "python.analysis.logLevel": "Trace", + "python.analysis.typeCheckingMode": "basic", + + "python.testing.pytestArgs": ["."], + "python.testing.cwd": "api/src", + "python.testing.pytestEnabled": true, + "python.testing.unittestEnabled": false, + "python.analysis.extraPaths": ["api/src"] +} diff --git a/IaC/main.bicep b/IaC/main.bicep new file mode 100644 index 00000000..d15cacb0 --- /dev/null +++ b/IaC/main.bicep @@ -0,0 +1,34 @@ +@description('Specifies the location for resources.') +param location string = 'norwayeast' +@allowed(['dev', 'test', 'prod']) +param environment string + +@maxValue(730) +param logRetentionDays int + + +resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021-12-01-preview' = { + name: 'lcm-${environment}-logWorkspace' + location: location + properties: { + sku: { + name: 'PerGB2018' + } + } +} + +resource appInsight 'Microsoft.Insights/components@2020-02-02' = { + name: 'lcm-${environment}-logs' + location: location + kind: 'web' + properties: { + Application_Type: 'web' + Flow_Type: 'Bluefield' + IngestionMode: 'LogAnalytics' + publicNetworkAccessForIngestion: 'Enabled' + publicNetworkAccessForQuery: 'Enabled' + Request_Source: 'rest' + RetentionInDays: logRetentionDays + WorkspaceResourceId: logAnalyticsWorkspace.id + } +} diff --git a/README.md b/README.md index b7957e0b..f752479b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Lost Circulation Material Optimizer +[![License][license-badge]][license] ![CI](https://github.com/equinor/lcm/workflows/CI/badge.svg) @@ -11,29 +12,6 @@ This repository is the result from the merger of the two summer intern projects ![plot](doc/bridge-plot.png) -Deployed environments: - - [Test](https://proxy-lost-circulation-material-test.radix.equinor.com) - - [Production](https://lost-circulation-material.app.radix.equinor.com) - -## Requirements - -- docker -- docker-compose - -## Running - -1. Create a copy of `.env-template` called `.env` and populate it with values. -2. Build the containers - - ```sh - docker compose build - ``` - -3. Start the project - - ```sh - docker compose up - ``` ## Contributing @@ -41,10 +19,11 @@ Pull requests are welcome. For major changes, please open an issue first to disc Please make sure to update tests as appropriate. -## Operational runbook + +## Development -[RUNBOOK](runbook.md) +See the [docs](https://varia.equinor.com/docs/default/system/lcm) if you want to start developing. -## License -[MIT](LICENSE) +[license-badge]: https://img.shields.io/badge/License-MIT-yellow.svg +[license]: https://github.com/equinor/lcm/blob/master/LICENSE.md diff --git a/api/Dockerfile b/api/Dockerfile index fcee134d..a1e5dca2 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.12-slim +FROM python:3.14-slim ENV PYTHONUNBUFFERED=1 ENV FLASK_APP=/app/src/app.py diff --git a/api/poetry.lock b/api/poetry.lock index 129d70b8..0fe1b42a 100644 --- a/api/poetry.lock +++ b/api/poetry.lock @@ -1,4 +1,19 @@ -# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand. + +[[package]] +name = "asgiref" +version = "3.8.1" +description = "ASGI specs, helper code, and adapters" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "asgiref-3.8.1-py3-none-any.whl", hash = "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47"}, + {file = "asgiref-3.8.1.tar.gz", hash = "sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590"}, +] + +[package.extras] +tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] [[package]] name = "azure-common" @@ -14,23 +29,39 @@ files = [ [[package]] name = "azure-core" -version = "1.32.0" +version = "1.38.2" description = "Microsoft Azure Core Library for Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["main"] files = [ - {file = "azure_core-1.32.0-py3-none-any.whl", hash = "sha256:eac191a0efb23bfa83fddf321b27b122b4ec847befa3091fa736a5c32c50d7b4"}, - {file = "azure_core-1.32.0.tar.gz", hash = "sha256:22b3c35d6b2dae14990f6c1be2912bf23ffe50b220e708a28ab1bb92b1c730e5"}, + {file = "azure_core-1.38.2-py3-none-any.whl", hash = "sha256:074806c75cf239ea284a33a66827695ef7aeddac0b4e19dda266a93e4665ead9"}, + {file = "azure_core-1.38.2.tar.gz", hash = "sha256:67562857cb979217e48dc60980243b61ea115b77326fa93d83b729e7ff0482e7"}, ] [package.dependencies] requests = ">=2.21.0" -six = ">=1.11.0" typing-extensions = ">=4.6.0" [package.extras] aio = ["aiohttp (>=3.0)"] +tracing = ["opentelemetry-api (>=1.26,<2.0)"] + +[[package]] +name = "azure-core-tracing-opentelemetry" +version = "1.0.0b11" +description = "Microsoft Azure Azure Core OpenTelemetry plugin Library for Python" +optional = false +python-versions = ">=3.7" +groups = ["main"] +files = [ + {file = "azure-core-tracing-opentelemetry-1.0.0b11.tar.gz", hash = "sha256:a230d1555838b5d07b7594221cd639ea7bc24e29c881e5675e311c6067bad4f5"}, + {file = "azure_core_tracing_opentelemetry-1.0.0b11-py3-none-any.whl", hash = "sha256:016cefcaff2900fb5cdb7a8a7abd03e9c266622c06e26b3fe6dafa54c4b48bf5"}, +] + +[package.dependencies] +azure-core = ">=1.24.0,<2.0.0" +opentelemetry-api = ">=1.12.0,<2.0.0" [[package]] name = "azure-cosmosdb-nspkg" @@ -66,6 +97,71 @@ cryptography = "*" python-dateutil = "*" requests = "*" +[[package]] +name = "azure-identity" +version = "1.25.2" +description = "Microsoft Azure Identity Library for Python" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "azure_identity-1.25.2-py3-none-any.whl", hash = "sha256:1b40060553d01a72ba0d708b9a46d0f61f56312e215d8896d836653ffdc6753d"}, + {file = "azure_identity-1.25.2.tar.gz", hash = "sha256:030dbaa720266c796221c6cdbd1999b408c079032c919fef725fcc348a540fe9"}, +] + +[package.dependencies] +azure-core = ">=1.31.0" +cryptography = ">=2.5" +msal = ">=1.31.0" +msal-extensions = ">=1.2.0" +typing-extensions = ">=4.0.0" + +[[package]] +name = "azure-monitor-opentelemetry" +version = "1.8.6" +description = "Microsoft Azure Monitor Opentelemetry Distro Client Library for Python" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "azure_monitor_opentelemetry-1.8.6-py3-none-any.whl", hash = "sha256:2323eeba15bd2f016806e15f5bd6d24ddd62cc06beae0a06ab3fcfab38d3d120"}, + {file = "azure_monitor_opentelemetry-1.8.6.tar.gz", hash = "sha256:8301c377f2c0550dc9b87b273b746d5841ef8e5117b6c542c9a6f7f3c7f34c20"}, +] + +[package.dependencies] +azure-core = ">=1.28.0,<2.0.0" +azure-core-tracing-opentelemetry = ">=1.0.0b11,<1.1.0" +azure-monitor-opentelemetry-exporter = ">=1.0.0b47,<1.1.0" +opentelemetry-instrumentation-django = "0.60b0" +opentelemetry-instrumentation-fastapi = "0.60b0" +opentelemetry-instrumentation-flask = "0.60b0" +opentelemetry-instrumentation-psycopg2 = "0.60b0" +opentelemetry-instrumentation-requests = "0.60b0" +opentelemetry-instrumentation-urllib = "0.60b0" +opentelemetry-instrumentation-urllib3 = "0.60b0" +opentelemetry-resource-detector-azure = ">=0.1.5,<1.0.0" +opentelemetry-sdk = "1.39" + +[[package]] +name = "azure-monitor-opentelemetry-exporter" +version = "1.0.0b48" +description = "Microsoft Azure Monitor Opentelemetry Exporter Client Library for Python" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "azure_monitor_opentelemetry_exporter-1.0.0b48-py2.py3-none-any.whl", hash = "sha256:da17ac143b84516e639ce06f2d7119b7a7af99214bb773c652137e620e868eb7"}, + {file = "azure_monitor_opentelemetry_exporter-1.0.0b48.tar.gz", hash = "sha256:5773def013e508efffa55a17768409be4b2ba369724766a89775fdc0101cc4c1"}, +] + +[package.dependencies] +azure-core = ">=1.28.0,<2.0.0" +azure-identity = ">=1.17,<2.0" +msrest = ">=0.6.10" +opentelemetry-api = "1.39" +opentelemetry-sdk = "1.39" +psutil = ">=5.9,<8" + [[package]] name = "azure-nspkg" version = "3.0.2" @@ -81,14 +177,14 @@ files = [ [[package]] name = "azure-storage-blob" -version = "12.24.1" +version = "12.28.0" description = "Microsoft Azure Blob Storage Client Library for Python" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["main"] files = [ - {file = "azure_storage_blob-12.24.1-py3-none-any.whl", hash = "sha256:77fb823fdbac7f3c11f7d86a5892e2f85e161e8440a7489babe2195bf248f09e"}, - {file = "azure_storage_blob-12.24.1.tar.gz", hash = "sha256:052b2a1ea41725ba12e2f4f17be85a54df1129e13ea0321f5a2fcc851cbf47d4"}, + {file = "azure_storage_blob-12.28.0-py3-none-any.whl", hash = "sha256:00fb1db28bf6a7b7ecaa48e3b1d5c83bfadacc5a678b77826081304bd87d6461"}, + {file = "azure_storage_blob-12.28.0.tar.gz", hash = "sha256:e7d98ea108258d29aa0efbfd591b2e2075fa1722a2fae8699f0b3c9de11eff41"}, ] [package.dependencies] @@ -127,48 +223,54 @@ yaml = ["PyYAML"] [[package]] name = "black" -version = "25.1.0" +version = "26.3.1" description = "The uncompromising code formatter." optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "black-25.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:759e7ec1e050a15f89b770cefbf91ebee8917aac5c20483bc2d80a6c3a04df32"}, - {file = "black-25.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e519ecf93120f34243e6b0054db49c00a35f84f195d5bce7e9f5cfc578fc2da"}, - {file = "black-25.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:055e59b198df7ac0b7efca5ad7ff2516bca343276c466be72eb04a3bcc1f82d7"}, - {file = "black-25.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:db8ea9917d6f8fc62abd90d944920d95e73c83a5ee3383493e35d271aca872e9"}, - {file = "black-25.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a39337598244de4bae26475f77dda852ea00a93bd4c728e09eacd827ec929df0"}, - {file = "black-25.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:96c1c7cd856bba8e20094e36e0f948718dc688dba4a9d78c3adde52b9e6c2299"}, - {file = "black-25.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bce2e264d59c91e52d8000d507eb20a9aca4a778731a08cfff7e5ac4a4bb7096"}, - {file = "black-25.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:172b1dbff09f86ce6f4eb8edf9dede08b1fce58ba194c87d7a4f1a5aa2f5b3c2"}, - {file = "black-25.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4b60580e829091e6f9238c848ea6750efed72140b91b048770b64e74fe04908b"}, - {file = "black-25.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e2978f6df243b155ef5fa7e558a43037c3079093ed5d10fd84c43900f2d8ecc"}, - {file = "black-25.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b48735872ec535027d979e8dcb20bf4f70b5ac75a8ea99f127c106a7d7aba9f"}, - {file = "black-25.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:ea0213189960bda9cf99be5b8c8ce66bb054af5e9e861249cd23471bd7b0b3ba"}, - {file = "black-25.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8f0b18a02996a836cc9c9c78e5babec10930862827b1b724ddfe98ccf2f2fe4f"}, - {file = "black-25.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:afebb7098bfbc70037a053b91ae8437c3857482d3a690fefc03e9ff7aa9a5fd3"}, - {file = "black-25.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:030b9759066a4ee5e5aca28c3c77f9c64789cdd4de8ac1df642c40b708be6171"}, - {file = "black-25.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:a22f402b410566e2d1c950708c77ebf5ebd5d0d88a6a2e87c86d9fb48afa0d18"}, - {file = "black-25.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a1ee0a0c330f7b5130ce0caed9936a904793576ef4d2b98c40835d6a65afa6a0"}, - {file = "black-25.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f3df5f1bf91d36002b0a75389ca8663510cf0531cca8aa5c1ef695b46d98655f"}, - {file = "black-25.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d9e6827d563a2c820772b32ce8a42828dc6790f095f441beef18f96aa6f8294e"}, - {file = "black-25.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:bacabb307dca5ebaf9c118d2d2f6903da0d62c9faa82bd21a33eecc319559355"}, - {file = "black-25.1.0-py3-none-any.whl", hash = "sha256:95e8176dae143ba9097f351d174fdaf0ccd29efb414b362ae3fd72bf0f710717"}, - {file = "black-25.1.0.tar.gz", hash = "sha256:33496d5cd1222ad73391352b4ae8da15253c5de89b93a80b3e2c8d9a19ec2666"}, + {file = "black-26.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:86a8b5035fce64f5dcd1b794cf8ec4d31fe458cf6ce3986a30deb434df82a1d2"}, + {file = "black-26.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5602bdb96d52d2d0672f24f6ffe5218795736dd34807fd0fd55ccd6bf206168b"}, + {file = "black-26.3.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c54a4a82e291a1fee5137371ab488866b7c86a3305af4026bdd4dc78642e1ac"}, + {file = "black-26.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:6e131579c243c98f35bce64a7e08e87fb2d610544754675d4a0e73a070a5aa3a"}, + {file = "black-26.3.1-cp310-cp310-win_arm64.whl", hash = "sha256:5ed0ca58586c8d9a487352a96b15272b7fa55d139fc8496b519e78023a8dab0a"}, + {file = "black-26.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:28ef38aee69e4b12fda8dba75e21f9b4f979b490c8ac0baa7cb505369ac9e1ff"}, + {file = "black-26.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bf9bf162ed91a26f1adba8efda0b573bc6924ec1408a52cc6f82cb73ec2b142c"}, + {file = "black-26.3.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:474c27574d6d7037c1bc875a81d9be0a9a4f9ee95e62800dab3cfaadbf75acd5"}, + {file = "black-26.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:5e9d0d86df21f2e1677cc4bd090cd0e446278bcbbe49bf3659c308c3e402843e"}, + {file = "black-26.3.1-cp311-cp311-win_arm64.whl", hash = "sha256:9a5e9f45e5d5e1c5b5c29b3bd4265dcc90e8b92cf4534520896ed77f791f4da5"}, + {file = "black-26.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b5e6f89631eb88a7302d416594a32faeee9fb8fb848290da9d0a5f2903519fc1"}, + {file = "black-26.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:41cd2012d35b47d589cb8a16faf8a32ef7a336f56356babd9fcf70939ad1897f"}, + {file = "black-26.3.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f76ff19ec5297dd8e66eb64deda23631e642c9393ab592826fd4bdc97a4bce7"}, + {file = "black-26.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:ddb113db38838eb9f043623ba274cfaf7d51d5b0c22ecb30afe58b1bb8322983"}, + {file = "black-26.3.1-cp312-cp312-win_arm64.whl", hash = "sha256:dfdd51fc3e64ea4f35873d1b3fb25326773d55d2329ff8449139ebaad7357efb"}, + {file = "black-26.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:855822d90f884905362f602880ed8b5df1b7e3ee7d0db2502d4388a954cc8c54"}, + {file = "black-26.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8a33d657f3276328ce00e4d37fe70361e1ec7614da5d7b6e78de5426cb56332f"}, + {file = "black-26.3.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f1cd08e99d2f9317292a311dfe578fd2a24b15dbce97792f9c4d752275c1fa56"}, + {file = "black-26.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:c7e72339f841b5a237ff14f7d3880ddd0fc7f98a1199e8c4327f9a4f478c1839"}, + {file = "black-26.3.1-cp313-cp313-win_arm64.whl", hash = "sha256:afc622538b430aa4c8c853f7f63bc582b3b8030fd8c80b70fb5fa5b834e575c2"}, + {file = "black-26.3.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2d6bfaf7fd0993b420bed691f20f9492d53ce9a2bcccea4b797d34e947318a78"}, + {file = "black-26.3.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f89f2ab047c76a9c03f78d0d66ca519e389519902fa27e7a91117ef7611c0568"}, + {file = "black-26.3.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b07fc0dab849d24a80a29cfab8d8a19187d1c4685d8a5e6385a5ce323c1f015f"}, + {file = "black-26.3.1-cp314-cp314-win_amd64.whl", hash = "sha256:0126ae5b7c09957da2bdbd91a9ba1207453feada9e9fe51992848658c6c8e01c"}, + {file = "black-26.3.1-cp314-cp314-win_arm64.whl", hash = "sha256:92c0ec1f2cc149551a2b7b47efc32c866406b6891b0ee4625e95967c8f4acfb1"}, + {file = "black-26.3.1-py3-none-any.whl", hash = "sha256:2bd5aa94fc267d38bb21a70d7410a89f1a1d318841855f698746f8e7f51acd1b"}, + {file = "black-26.3.1.tar.gz", hash = "sha256:2c50f5063a9641c7eed7795014ba37b0f5fa227f3d408b968936e24bc0566b07"}, ] [package.dependencies] click = ">=8.0.0" mypy-extensions = ">=0.4.3" packaging = ">=22.0" -pathspec = ">=0.9.0" +pathspec = ">=1.0.0" platformdirs = ">=2" +pytokens = ">=0.4.0,<0.5.0" [package.extras] colorama = ["colorama (>=0.4.3)"] d = ["aiohttp (>=3.10)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -uvloop = ["uvloop (>=0.15.2)"] +uvloop = ["uvloop (>=0.15.2) ; sys_platform != \"win32\"", "winloop (>=0.5.0) ; sys_platform == \"win32\""] [[package]] name = "blinker" @@ -184,14 +286,14 @@ files = [ [[package]] name = "cachetools" -version = "5.5.2" +version = "7.0.1" description = "Extensible memoizing collections and decorators" optional = false -python-versions = ">=3.7" +python-versions = ">=3.10" groups = ["main"] files = [ - {file = "cachetools-5.5.2-py3-none-any.whl", hash = "sha256:d26a22bcc62eb95c3beabd9f1ee5e820d3d2704fe2967cbe350e20c8ffcd3f0a"}, - {file = "cachetools-5.5.2.tar.gz", hash = "sha256:1a661caa9175d26759571b2e19580f9d6393969e5dfca11fdb1f947a23e640d4"}, + {file = "cachetools-7.0.1-py3-none-any.whl", hash = "sha256:8f086515c254d5664ae2146d14fc7f65c9a4bce75152eb247e5a9c5e6d7b2ecf"}, + {file = "cachetools-7.0.1.tar.gz", hash = "sha256:e31e579d2c5b6e2944177a0397150d312888ddf4e16e12f1016068f0c03b8341"}, ] [[package]] @@ -208,83 +310,100 @@ files = [ [[package]] name = "cffi" -version = "1.17.1" +version = "2.0.0" description = "Foreign Function Interface for Python calling C code." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["main"] files = [ - {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, - {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, - {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, - {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, - {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, - {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, - {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, - {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, - {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, - {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, - {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, - {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, - {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, - {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, - {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, - {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, - {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, - {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, - {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, - {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, - {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, - {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, - {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, - {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, - {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, - {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, - {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, - {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, - {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, - {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, - {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, - {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, - {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, - {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, - {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, - {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, - {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, + {file = "cffi-2.0.0-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:0cf2d91ecc3fcc0625c2c530fe004f82c110405f101548512cce44322fa8ac44"}, + {file = "cffi-2.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f73b96c41e3b2adedc34a7356e64c8eb96e03a3782b535e043a986276ce12a49"}, + {file = "cffi-2.0.0-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:53f77cbe57044e88bbd5ed26ac1d0514d2acf0591dd6bb02a3ae37f76811b80c"}, + {file = "cffi-2.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3e837e369566884707ddaf85fc1744b47575005c0a229de3327f8f9a20f4efeb"}, + {file = "cffi-2.0.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:5eda85d6d1879e692d546a078b44251cdd08dd1cfb98dfb77b670c97cee49ea0"}, + {file = "cffi-2.0.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9332088d75dc3241c702d852d4671613136d90fa6881da7d770a483fd05248b4"}, + {file = "cffi-2.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc7de24befaeae77ba923797c7c87834c73648a05a4bde34b3b7e5588973a453"}, + {file = "cffi-2.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cf364028c016c03078a23b503f02058f1814320a56ad535686f90565636a9495"}, + {file = "cffi-2.0.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e11e82b744887154b182fd3e7e8512418446501191994dbf9c9fc1f32cc8efd5"}, + {file = "cffi-2.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8ea985900c5c95ce9db1745f7933eeef5d314f0565b27625d9a10ec9881e1bfb"}, + {file = "cffi-2.0.0-cp310-cp310-win32.whl", hash = "sha256:1f72fb8906754ac8a2cc3f9f5aaa298070652a0ffae577e0ea9bd480dc3c931a"}, + {file = "cffi-2.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:b18a3ed7d5b3bd8d9ef7a8cb226502c6bf8308df1525e1cc676c3680e7176739"}, + {file = "cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe"}, + {file = "cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c"}, + {file = "cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92"}, + {file = "cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93"}, + {file = "cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5"}, + {file = "cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664"}, + {file = "cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26"}, + {file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9"}, + {file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414"}, + {file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743"}, + {file = "cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5"}, + {file = "cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5"}, + {file = "cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d"}, + {file = "cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d"}, + {file = "cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c"}, + {file = "cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe"}, + {file = "cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062"}, + {file = "cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e"}, + {file = "cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037"}, + {file = "cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba"}, + {file = "cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94"}, + {file = "cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187"}, + {file = "cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18"}, + {file = "cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5"}, + {file = "cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6"}, + {file = "cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb"}, + {file = "cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca"}, + {file = "cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b"}, + {file = "cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b"}, + {file = "cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2"}, + {file = "cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3"}, + {file = "cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26"}, + {file = "cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c"}, + {file = "cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b"}, + {file = "cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27"}, + {file = "cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75"}, + {file = "cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91"}, + {file = "cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5"}, + {file = "cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13"}, + {file = "cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b"}, + {file = "cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c"}, + {file = "cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef"}, + {file = "cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775"}, + {file = "cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205"}, + {file = "cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1"}, + {file = "cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f"}, + {file = "cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25"}, + {file = "cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad"}, + {file = "cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9"}, + {file = "cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d"}, + {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c"}, + {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8"}, + {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc"}, + {file = "cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592"}, + {file = "cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512"}, + {file = "cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4"}, + {file = "cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e"}, + {file = "cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6"}, + {file = "cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9"}, + {file = "cffi-2.0.0-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:fe562eb1a64e67dd297ccc4f5addea2501664954f2692b69a76449ec7913ecbf"}, + {file = "cffi-2.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:de8dad4425a6ca6e4e5e297b27b5c824ecc7581910bf9aee86cb6835e6812aa7"}, + {file = "cffi-2.0.0-cp39-cp39-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:4647afc2f90d1ddd33441e5b0e85b16b12ddec4fca55f0d9671fef036ecca27c"}, + {file = "cffi-2.0.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3f4d46d8b35698056ec29bca21546e1551a205058ae1a181d871e278b0b28165"}, + {file = "cffi-2.0.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:e6e73b9e02893c764e7e8d5bb5ce277f1a009cd5243f8228f75f842bf937c534"}, + {file = "cffi-2.0.0-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:cb527a79772e5ef98fb1d700678fe031e353e765d1ca2d409c92263c6d43e09f"}, + {file = "cffi-2.0.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:61d028e90346df14fedc3d1e5441df818d095f3b87d286825dfcbd6459b7ef63"}, + {file = "cffi-2.0.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:0f6084a0ea23d05d20c3edcda20c3d006f9b6f3fefeac38f59262e10cef47ee2"}, + {file = "cffi-2.0.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1cd13c99ce269b3ed80b417dcd591415d3372bcac067009b6e0f59c7d4015e65"}, + {file = "cffi-2.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:89472c9762729b5ae1ad974b777416bfda4ac5642423fa93bd57a09204712322"}, + {file = "cffi-2.0.0-cp39-cp39-win32.whl", hash = "sha256:2081580ebb843f759b9f617314a24ed5738c51d2aee65d31e02f6f7a2b97707a"}, + {file = "cffi-2.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:b882b3df248017dba09d6b16defe9b5c407fe32fc7c65a9c69798e6175601be9"}, + {file = "cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529"}, ] [package.dependencies] -pycparser = "*" +pycparser = {version = "*", markers = "implementation_name != \"PyPy\""} [[package]] name = "charset-normalizer" @@ -418,75 +537,93 @@ markers = {main = "platform_system == \"Windows\"", dev = "platform_system == \" [[package]] name = "contourpy" -version = "1.3.1" +version = "1.3.3" description = "Python library for calculating contours of 2D quadrilateral grids" optional = false -python-versions = ">=3.10" +python-versions = ">=3.11" groups = ["main"] files = [ - {file = "contourpy-1.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a045f341a77b77e1c5de31e74e966537bba9f3c4099b35bf4c2e3939dd54cdab"}, - {file = "contourpy-1.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:500360b77259914f7805af7462e41f9cb7ca92ad38e9f94d6c8641b089338124"}, - {file = "contourpy-1.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2f926efda994cdf3c8d3fdb40b9962f86edbc4457e739277b961eced3d0b4c1"}, - {file = "contourpy-1.3.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:adce39d67c0edf383647a3a007de0a45fd1b08dedaa5318404f1a73059c2512b"}, - {file = "contourpy-1.3.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abbb49fb7dac584e5abc6636b7b2a7227111c4f771005853e7d25176daaf8453"}, - {file = "contourpy-1.3.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0cffcbede75c059f535725c1680dfb17b6ba8753f0c74b14e6a9c68c29d7ea3"}, - {file = "contourpy-1.3.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ab29962927945d89d9b293eabd0d59aea28d887d4f3be6c22deaefbb938a7277"}, - {file = "contourpy-1.3.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:974d8145f8ca354498005b5b981165b74a195abfae9a8129df3e56771961d595"}, - {file = "contourpy-1.3.1-cp310-cp310-win32.whl", hash = "sha256:ac4578ac281983f63b400f7fe6c101bedc10651650eef012be1ccffcbacf3697"}, - {file = "contourpy-1.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:174e758c66bbc1c8576992cec9599ce8b6672b741b5d336b5c74e35ac382b18e"}, - {file = "contourpy-1.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3e8b974d8db2c5610fb4e76307e265de0edb655ae8169e8b21f41807ccbeec4b"}, - {file = "contourpy-1.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:20914c8c973f41456337652a6eeca26d2148aa96dd7ac323b74516988bea89fc"}, - {file = "contourpy-1.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19d40d37c1c3a4961b4619dd9d77b12124a453cc3d02bb31a07d58ef684d3d86"}, - {file = "contourpy-1.3.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:113231fe3825ebf6f15eaa8bc1f5b0ddc19d42b733345eae0934cb291beb88b6"}, - {file = "contourpy-1.3.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4dbbc03a40f916a8420e420d63e96a1258d3d1b58cbdfd8d1f07b49fcbd38e85"}, - {file = "contourpy-1.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a04ecd68acbd77fa2d39723ceca4c3197cb2969633836ced1bea14e219d077c"}, - {file = "contourpy-1.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c414fc1ed8ee1dbd5da626cf3710c6013d3d27456651d156711fa24f24bd1291"}, - {file = "contourpy-1.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:31c1b55c1f34f80557d3830d3dd93ba722ce7e33a0b472cba0ec3b6535684d8f"}, - {file = "contourpy-1.3.1-cp311-cp311-win32.whl", hash = "sha256:f611e628ef06670df83fce17805c344710ca5cde01edfdc72751311da8585375"}, - {file = "contourpy-1.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:b2bdca22a27e35f16794cf585832e542123296b4687f9fd96822db6bae17bfc9"}, - {file = "contourpy-1.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0ffa84be8e0bd33410b17189f7164c3589c229ce5db85798076a3fa136d0e509"}, - {file = "contourpy-1.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805617228ba7e2cbbfb6c503858e626ab528ac2a32a04a2fe88ffaf6b02c32bc"}, - {file = "contourpy-1.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ade08d343436a94e633db932e7e8407fe7de8083967962b46bdfc1b0ced39454"}, - {file = "contourpy-1.3.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:47734d7073fb4590b4a40122b35917cd77be5722d80683b249dac1de266aac80"}, - {file = "contourpy-1.3.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2ba94a401342fc0f8b948e57d977557fbf4d515f03c67682dd5c6191cb2d16ec"}, - {file = "contourpy-1.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efa874e87e4a647fd2e4f514d5e91c7d493697127beb95e77d2f7561f6905bd9"}, - {file = "contourpy-1.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1bf98051f1045b15c87868dbaea84f92408337d4f81d0e449ee41920ea121d3b"}, - {file = "contourpy-1.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:61332c87493b00091423e747ea78200659dc09bdf7fd69edd5e98cef5d3e9a8d"}, - {file = "contourpy-1.3.1-cp312-cp312-win32.whl", hash = "sha256:e914a8cb05ce5c809dd0fe350cfbb4e881bde5e2a38dc04e3afe1b3e58bd158e"}, - {file = "contourpy-1.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:08d9d449a61cf53033612cb368f3a1b26cd7835d9b8cd326647efe43bca7568d"}, - {file = "contourpy-1.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a761d9ccfc5e2ecd1bf05534eda382aa14c3e4f9205ba5b1684ecfe400716ef2"}, - {file = "contourpy-1.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:523a8ee12edfa36f6d2a49407f705a6ef4c5098de4f498619787e272de93f2d5"}, - {file = "contourpy-1.3.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece6df05e2c41bd46776fbc712e0996f7c94e0d0543af1656956d150c4ca7c81"}, - {file = "contourpy-1.3.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:573abb30e0e05bf31ed067d2f82500ecfdaec15627a59d63ea2d95714790f5c2"}, - {file = "contourpy-1.3.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9fa36448e6a3a1a9a2ba23c02012c43ed88905ec80163f2ffe2421c7192a5d7"}, - {file = "contourpy-1.3.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ea9924d28fc5586bf0b42d15f590b10c224117e74409dd7a0be3b62b74a501c"}, - {file = "contourpy-1.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5b75aa69cb4d6f137b36f7eb2ace9280cfb60c55dc5f61c731fdf6f037f958a3"}, - {file = "contourpy-1.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:041b640d4ec01922083645a94bb3b2e777e6b626788f4095cf21abbe266413c1"}, - {file = "contourpy-1.3.1-cp313-cp313-win32.whl", hash = "sha256:36987a15e8ace5f58d4d5da9dca82d498c2bbb28dff6e5d04fbfcc35a9cb3a82"}, - {file = "contourpy-1.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:a7895f46d47671fa7ceec40f31fae721da51ad34bdca0bee83e38870b1f47ffd"}, - {file = "contourpy-1.3.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:9ddeb796389dadcd884c7eb07bd14ef12408aaae358f0e2ae24114d797eede30"}, - {file = "contourpy-1.3.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:19c1555a6801c2f084c7ddc1c6e11f02eb6a6016ca1318dd5452ba3f613a1751"}, - {file = "contourpy-1.3.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:841ad858cff65c2c04bf93875e384ccb82b654574a6d7f30453a04f04af71342"}, - {file = "contourpy-1.3.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4318af1c925fb9a4fb190559ef3eec206845f63e80fb603d47f2d6d67683901c"}, - {file = "contourpy-1.3.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:14c102b0eab282427b662cb590f2e9340a9d91a1c297f48729431f2dcd16e14f"}, - {file = "contourpy-1.3.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05e806338bfeaa006acbdeba0ad681a10be63b26e1b17317bfac3c5d98f36cda"}, - {file = "contourpy-1.3.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4d76d5993a34ef3df5181ba3c92fabb93f1eaa5729504fb03423fcd9f3177242"}, - {file = "contourpy-1.3.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:89785bb2a1980c1bd87f0cb1517a71cde374776a5f150936b82580ae6ead44a1"}, - {file = "contourpy-1.3.1-cp313-cp313t-win32.whl", hash = "sha256:8eb96e79b9f3dcadbad2a3891672f81cdcab7f95b27f28f1c67d75f045b6b4f1"}, - {file = "contourpy-1.3.1-cp313-cp313t-win_amd64.whl", hash = "sha256:287ccc248c9e0d0566934e7d606201abd74761b5703d804ff3df8935f523d546"}, - {file = "contourpy-1.3.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b457d6430833cee8e4b8e9b6f07aa1c161e5e0d52e118dc102c8f9bd7dd060d6"}, - {file = "contourpy-1.3.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb76c1a154b83991a3cbbf0dfeb26ec2833ad56f95540b442c73950af2013750"}, - {file = "contourpy-1.3.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:44a29502ca9c7b5ba389e620d44f2fbe792b1fb5734e8b931ad307071ec58c53"}, - {file = "contourpy-1.3.1.tar.gz", hash = "sha256:dfd97abd83335045a913e3bcc4a09c0ceadbe66580cf573fe961f4a825efa699"}, + {file = "contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1"}, + {file = "contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381"}, + {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:929ddf8c4c7f348e4c0a5a3a714b5c8542ffaa8c22954862a46ca1813b667ee7"}, + {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9e999574eddae35f1312c2b4b717b7885d4edd6cb46700e04f7f02db454e67c1"}, + {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf67e0e3f482cb69779dd3061b534eb35ac9b17f163d851e2a547d56dba0a3a"}, + {file = "contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db"}, + {file = "contourpy-1.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:598c3aaece21c503615fd59c92a3598b428b2f01bfb4b8ca9c4edeecc2438620"}, + {file = "contourpy-1.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:322ab1c99b008dad206d406bb61d014cf0174df491ae9d9d0fac6a6fda4f977f"}, + {file = "contourpy-1.3.3-cp311-cp311-win32.whl", hash = "sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff"}, + {file = "contourpy-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42"}, + {file = "contourpy-1.3.3-cp311-cp311-win_arm64.whl", hash = "sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470"}, + {file = "contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb"}, + {file = "contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6"}, + {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7"}, + {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8"}, + {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea"}, + {file = "contourpy-1.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1"}, + {file = "contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7"}, + {file = "contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411"}, + {file = "contourpy-1.3.3-cp312-cp312-win32.whl", hash = "sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69"}, + {file = "contourpy-1.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b"}, + {file = "contourpy-1.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc"}, + {file = "contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5"}, + {file = "contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1"}, + {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286"}, + {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5"}, + {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67"}, + {file = "contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9"}, + {file = "contourpy-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659"}, + {file = "contourpy-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7"}, + {file = "contourpy-1.3.3-cp313-cp313-win32.whl", hash = "sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d"}, + {file = "contourpy-1.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263"}, + {file = "contourpy-1.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9"}, + {file = "contourpy-1.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d"}, + {file = "contourpy-1.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216"}, + {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae"}, + {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20"}, + {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99"}, + {file = "contourpy-1.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b"}, + {file = "contourpy-1.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a"}, + {file = "contourpy-1.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e"}, + {file = "contourpy-1.3.3-cp313-cp313t-win32.whl", hash = "sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3"}, + {file = "contourpy-1.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8"}, + {file = "contourpy-1.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301"}, + {file = "contourpy-1.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fde6c716d51c04b1c25d0b90364d0be954624a0ee9d60e23e850e8d48353d07a"}, + {file = "contourpy-1.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cbedb772ed74ff5be440fa8eee9bd49f64f6e3fc09436d9c7d8f1c287b121d77"}, + {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5"}, + {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4"}, + {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36"}, + {file = "contourpy-1.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3"}, + {file = "contourpy-1.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b"}, + {file = "contourpy-1.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36"}, + {file = "contourpy-1.3.3-cp314-cp314-win32.whl", hash = "sha256:66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d"}, + {file = "contourpy-1.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd"}, + {file = "contourpy-1.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339"}, + {file = "contourpy-1.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:33c82d0138c0a062380332c861387650c82e4cf1747aaa6938b9b6516762e772"}, + {file = "contourpy-1.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ea37e7b45949df430fe649e5de8351c423430046a2af20b1c1961cae3afcda77"}, + {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13"}, + {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe"}, + {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f"}, + {file = "contourpy-1.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0"}, + {file = "contourpy-1.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4"}, + {file = "contourpy-1.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f"}, + {file = "contourpy-1.3.3-cp314-cp314t-win32.whl", hash = "sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae"}, + {file = "contourpy-1.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc"}, + {file = "contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b"}, + {file = "contourpy-1.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497"}, + {file = "contourpy-1.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8"}, + {file = "contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e"}, + {file = "contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ed3657edf08512fc3fe81b510e35c2012fbd3081d2e26160f27ca28affec989"}, + {file = "contourpy-1.3.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77"}, + {file = "contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880"}, ] [package.dependencies] -numpy = ">=1.23" +numpy = ">=1.25" [package.extras] bokeh = ["bokeh", "selenium"] docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"] -mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.11.1)", "types-Pillow"] +mypy = ["bokeh", "contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.17.0)", "types-Pillow"] test = ["Pillow", "contourpy[test-no-images]", "matplotlib"] test-no-images = ["pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist", "wurlitzer"] @@ -568,56 +705,74 @@ toml = ["tomli ; python_full_version <= \"3.11.0a6\""] [[package]] name = "cryptography" -version = "44.0.1" +version = "46.0.5" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false -python-versions = "!=3.9.0,!=3.9.1,>=3.7" -groups = ["main"] -files = [ - {file = "cryptography-44.0.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf688f615c29bfe9dfc44312ca470989279f0e94bb9f631f85e3459af8efc009"}, - {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd7c7e2d71d908dc0f8d2027e1604102140d84b155e658c20e8ad1304317691f"}, - {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:887143b9ff6bad2b7570da75a7fe8bbf5f65276365ac259a5d2d5147a73775f2"}, - {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:322eb03ecc62784536bc173f1483e76747aafeb69c8728df48537eb431cd1911"}, - {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:21377472ca4ada2906bc313168c9dc7b1d7ca417b63c1c3011d0c74b7de9ae69"}, - {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:df978682c1504fc93b3209de21aeabf2375cb1571d4e61907b3e7a2540e83026"}, - {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:eb3889330f2a4a148abead555399ec9a32b13b7c8ba969b72d8e500eb7ef84cd"}, - {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:8e6a85a93d0642bd774460a86513c5d9d80b5c002ca9693e63f6e540f1815ed0"}, - {file = "cryptography-44.0.1-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:6f76fdd6fd048576a04c5210d53aa04ca34d2ed63336d4abd306d0cbe298fddf"}, - {file = "cryptography-44.0.1-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6c8acf6f3d1f47acb2248ec3ea261171a671f3d9428e34ad0357148d492c7864"}, - {file = "cryptography-44.0.1-cp37-abi3-win32.whl", hash = "sha256:24979e9f2040c953a94bf3c6782e67795a4c260734e5264dceea65c8f4bae64a"}, - {file = "cryptography-44.0.1-cp37-abi3-win_amd64.whl", hash = "sha256:fd0ee90072861e276b0ff08bd627abec29e32a53b2be44e41dbcdf87cbee2b00"}, - {file = "cryptography-44.0.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:a2d8a7045e1ab9b9f803f0d9531ead85f90c5f2859e653b61497228b18452008"}, - {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8272f257cf1cbd3f2e120f14c68bff2b6bdfcc157fafdee84a1b795efd72862"}, - {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e8d181e90a777b63f3f0caa836844a1182f1f265687fac2115fcf245f5fbec3"}, - {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:436df4f203482f41aad60ed1813811ac4ab102765ecae7a2bbb1dbb66dcff5a7"}, - {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4f422e8c6a28cf8b7f883eb790695d6d45b0c385a2583073f3cec434cc705e1a"}, - {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:72198e2b5925155497a5a3e8c216c7fb3e64c16ccee11f0e7da272fa93b35c4c"}, - {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:2a46a89ad3e6176223b632056f321bc7de36b9f9b93b2cc1cccf935a3849dc62"}, - {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:53f23339864b617a3dfc2b0ac8d5c432625c80014c25caac9082314e9de56f41"}, - {file = "cryptography-44.0.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:888fcc3fce0c888785a4876ca55f9f43787f4c5c1cc1e2e0da71ad481ff82c5b"}, - {file = "cryptography-44.0.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:00918d859aa4e57db8299607086f793fa7813ae2ff5a4637e318a25ef82730f7"}, - {file = "cryptography-44.0.1-cp39-abi3-win32.whl", hash = "sha256:9b336599e2cb77b1008cb2ac264b290803ec5e8e89d618a5e978ff5eb6f715d9"}, - {file = "cryptography-44.0.1-cp39-abi3-win_amd64.whl", hash = "sha256:e403f7f766ded778ecdb790da786b418a9f2394f36e8cc8b796cc056ab05f44f"}, - {file = "cryptography-44.0.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:1f9a92144fa0c877117e9748c74501bea842f93d21ee00b0cf922846d9d0b183"}, - {file = "cryptography-44.0.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:610a83540765a8d8ce0f351ce42e26e53e1f774a6efb71eb1b41eb01d01c3d12"}, - {file = "cryptography-44.0.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:5fed5cd6102bb4eb843e3315d2bf25fede494509bddadb81e03a859c1bc17b83"}, - {file = "cryptography-44.0.1-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:f4daefc971c2d1f82f03097dc6f216744a6cd2ac0f04c68fb935ea2ba2a0d420"}, - {file = "cryptography-44.0.1-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:94f99f2b943b354a5b6307d7e8d19f5c423a794462bde2bf310c770ba052b1c4"}, - {file = "cryptography-44.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d9c5b9f698a83c8bd71e0f4d3f9f839ef244798e5ffe96febfa9714717db7af7"}, - {file = "cryptography-44.0.1.tar.gz", hash = "sha256:f51f5705ab27898afda1aaa430f34ad90dc117421057782022edf0600bec5f14"}, +python-versions = "!=3.9.0,!=3.9.1,>=3.8" +groups = ["main"] +files = [ + {file = "cryptography-46.0.5-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:351695ada9ea9618b3500b490ad54c739860883df6c1f555e088eaf25b1bbaad"}, + {file = "cryptography-46.0.5-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c18ff11e86df2e28854939acde2d003f7984f721eba450b56a200ad90eeb0e6b"}, + {file = "cryptography-46.0.5-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d7e3d356b8cd4ea5aff04f129d5f66ebdc7b6f8eae802b93739ed520c47c79b"}, + {file = "cryptography-46.0.5-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:50bfb6925eff619c9c023b967d5b77a54e04256c4281b0e21336a130cd7fc263"}, + {file = "cryptography-46.0.5-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:803812e111e75d1aa73690d2facc295eaefd4439be1023fefc4995eaea2af90d"}, + {file = "cryptography-46.0.5-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3ee190460e2fbe447175cda91b88b84ae8322a104fc27766ad09428754a618ed"}, + {file = "cryptography-46.0.5-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:f145bba11b878005c496e93e257c1e88f154d278d2638e6450d17e0f31e558d2"}, + {file = "cryptography-46.0.5-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:e9251e3be159d1020c4030bd2e5f84d6a43fe54b6c19c12f51cde9542a2817b2"}, + {file = "cryptography-46.0.5-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:47fb8a66058b80e509c47118ef8a75d14c455e81ac369050f20ba0d23e77fee0"}, + {file = "cryptography-46.0.5-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:4c3341037c136030cb46e4b1e17b7418ea4cbd9dd207e4a6f3b2b24e0d4ac731"}, + {file = "cryptography-46.0.5-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:890bcb4abd5a2d3f852196437129eb3667d62630333aacc13dfd470fad3aaa82"}, + {file = "cryptography-46.0.5-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:80a8d7bfdf38f87ca30a5391c0c9ce4ed2926918e017c29ddf643d0ed2778ea1"}, + {file = "cryptography-46.0.5-cp311-abi3-win32.whl", hash = "sha256:60ee7e19e95104d4c03871d7d7dfb3d22ef8a9b9c6778c94e1c8fcc8365afd48"}, + {file = "cryptography-46.0.5-cp311-abi3-win_amd64.whl", hash = "sha256:38946c54b16c885c72c4f59846be9743d699eee2b69b6988e0a00a01f46a61a4"}, + {file = "cryptography-46.0.5-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:94a76daa32eb78d61339aff7952ea819b1734b46f73646a07decb40e5b3448e2"}, + {file = "cryptography-46.0.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5be7bf2fb40769e05739dd0046e7b26f9d4670badc7b032d6ce4db64dddc0678"}, + {file = "cryptography-46.0.5-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fe346b143ff9685e40192a4960938545c699054ba11d4f9029f94751e3f71d87"}, + {file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:c69fd885df7d089548a42d5ec05be26050ebcd2283d89b3d30676eb32ff87dee"}, + {file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:8293f3dea7fc929ef7240796ba231413afa7b68ce38fd21da2995549f5961981"}, + {file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:1abfdb89b41c3be0365328a410baa9df3ff8a9110fb75e7b52e66803ddabc9a9"}, + {file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:d66e421495fdb797610a08f43b05269e0a5ea7f5e652a89bfd5a7d3c1dee3648"}, + {file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:4e817a8920bfbcff8940ecfd60f23d01836408242b30f1a708d93198393a80b4"}, + {file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:68f68d13f2e1cb95163fa3b4db4bf9a159a418f5f6e7242564fc75fcae667fd0"}, + {file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:a3d1fae9863299076f05cb8a778c467578262fae09f9dc0ee9b12eb4268ce663"}, + {file = "cryptography-46.0.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c4143987a42a2397f2fc3b4d7e3a7d313fbe684f67ff443999e803dd75a76826"}, + {file = "cryptography-46.0.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:7d731d4b107030987fd61a7f8ab512b25b53cef8f233a97379ede116f30eb67d"}, + {file = "cryptography-46.0.5-cp314-cp314t-win32.whl", hash = "sha256:c3bcce8521d785d510b2aad26ae2c966092b7daa8f45dd8f44734a104dc0bc1a"}, + {file = "cryptography-46.0.5-cp314-cp314t-win_amd64.whl", hash = "sha256:4d8ae8659ab18c65ced284993c2265910f6c9e650189d4e3f68445ef82a810e4"}, + {file = "cryptography-46.0.5-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:4108d4c09fbbf2789d0c926eb4152ae1760d5a2d97612b92d508d96c861e4d31"}, + {file = "cryptography-46.0.5-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d1f30a86d2757199cb2d56e48cce14deddf1f9c95f1ef1b64ee91ea43fe2e18"}, + {file = "cryptography-46.0.5-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:039917b0dc418bb9f6edce8a906572d69e74bd330b0b3fea4f79dab7f8ddd235"}, + {file = "cryptography-46.0.5-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ba2a27ff02f48193fc4daeadf8ad2590516fa3d0adeeb34336b96f7fa64c1e3a"}, + {file = "cryptography-46.0.5-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:61aa400dce22cb001a98014f647dc21cda08f7915ceb95df0c9eaf84b4b6af76"}, + {file = "cryptography-46.0.5-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3ce58ba46e1bc2aac4f7d9290223cead56743fa6ab94a5d53292ffaac6a91614"}, + {file = "cryptography-46.0.5-cp38-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:420d0e909050490d04359e7fdb5ed7e667ca5c3c402b809ae2563d7e66a92229"}, + {file = "cryptography-46.0.5-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:582f5fcd2afa31622f317f80426a027f30dc792e9c80ffee87b993200ea115f1"}, + {file = "cryptography-46.0.5-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:bfd56bb4b37ed4f330b82402f6f435845a5f5648edf1ad497da51a8452d5d62d"}, + {file = "cryptography-46.0.5-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:a3d507bb6a513ca96ba84443226af944b0f7f47dcc9a399d110cd6146481d24c"}, + {file = "cryptography-46.0.5-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9f16fbdf4da055efb21c22d81b89f155f02ba420558db21288b3d0035bafd5f4"}, + {file = "cryptography-46.0.5-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:ced80795227d70549a411a4ab66e8ce307899fad2220ce5ab2f296e687eacde9"}, + {file = "cryptography-46.0.5-cp38-abi3-win32.whl", hash = "sha256:02f547fce831f5096c9a567fd41bc12ca8f11df260959ecc7c3202555cc47a72"}, + {file = "cryptography-46.0.5-cp38-abi3-win_amd64.whl", hash = "sha256:556e106ee01aa13484ce9b0239bca667be5004efb0aabbed28d353df86445595"}, + {file = "cryptography-46.0.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:3b4995dc971c9fb83c25aa44cf45f02ba86f71ee600d81091c2f0cbae116b06c"}, + {file = "cryptography-46.0.5-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:bc84e875994c3b445871ea7181d424588171efec3e185dced958dad9e001950a"}, + {file = "cryptography-46.0.5-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:2ae6971afd6246710480e3f15824ed3029a60fc16991db250034efd0b9fb4356"}, + {file = "cryptography-46.0.5-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:d861ee9e76ace6cf36a6a89b959ec08e7bc2493ee39d07ffe5acb23ef46d27da"}, + {file = "cryptography-46.0.5-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:2b7a67c9cd56372f3249b39699f2ad479f6991e62ea15800973b956f4b73e257"}, + {file = "cryptography-46.0.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:8456928655f856c6e1533ff59d5be76578a7157224dbd9ce6872f25055ab9ab7"}, + {file = "cryptography-46.0.5.tar.gz", hash = "sha256:abace499247268e3757271b2f1e244b36b06f8515cf27c4d49468fc9eb16e93d"}, ] [package.dependencies] -cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} +cffi = {version = ">=2.0.0", markers = "python_full_version >= \"3.9.0\" and platform_python_implementation != \"PyPy\""} [package.extras] -docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=3.0.0) ; python_version >= \"3.8\""] +docs = ["sphinx (>=5.3.0)", "sphinx-inline-tabs", "sphinx-rtd-theme (>=3.0.0)"] docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"] -nox = ["nox (>=2024.4.15)", "nox[uv] (>=2024.3.2) ; python_version >= \"3.8\""] -pep8test = ["check-sdist ; python_version >= \"3.8\"", "click (>=8.0.1)", "mypy (>=1.4)", "ruff (>=0.3.6)"] +nox = ["nox[uv] (>=2024.4.15)"] +pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.14)", "ruff (>=0.11.11)"] sdist = ["build (>=1.0.0)"] ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi (>=2024)", "cryptography-vectors (==44.0.1)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] +test = ["certifi (>=2024)", "cryptography-vectors (==46.0.5)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] test-randomorder = ["pytest-randomly"] [[package]] @@ -650,22 +805,23 @@ files = [ [[package]] name = "flask" -version = "3.1.0" +version = "3.1.3" description = "A simple framework for building complex web applications." optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "flask-3.1.0-py3-none-any.whl", hash = "sha256:d667207822eb83f1c4b50949b1623c8fc8d51f2341d65f72e1a1815397551136"}, - {file = "flask-3.1.0.tar.gz", hash = "sha256:5f873c5184c897c8d9d1b05df1e3d01b14910ce69607a117bd3277098a5836ac"}, + {file = "flask-3.1.3-py3-none-any.whl", hash = "sha256:f4bcbefc124291925f1a26446da31a5178f9483862233b23c0c96a20701f670c"}, + {file = "flask-3.1.3.tar.gz", hash = "sha256:0ef0e52b8a9cd932855379197dd8f94047b359ca0a78695144304cb45f87c9eb"}, ] [package.dependencies] -blinker = ">=1.9" +blinker = ">=1.9.0" click = ">=8.1.3" -itsdangerous = ">=2.2" -Jinja2 = ">=3.1.2" -Werkzeug = ">=3.1" +itsdangerous = ">=2.2.0" +jinja2 = ">=3.1.2" +markupsafe = ">=2.1.1" +werkzeug = ">=3.1.0" [package.extras] async = ["asgiref (>=3.2)"] @@ -673,99 +829,99 @@ dotenv = ["python-dotenv"] [[package]] name = "fonttools" -version = "4.56.0" +version = "4.61.1" description = "Tools to manipulate font files" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" groups = ["main"] files = [ - {file = "fonttools-4.56.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:331954d002dbf5e704c7f3756028e21db07097c19722569983ba4d74df014000"}, - {file = "fonttools-4.56.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8d1613abd5af2f93c05867b3a3759a56e8bf97eb79b1da76b2bc10892f96ff16"}, - {file = "fonttools-4.56.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:705837eae384fe21cee5e5746fd4f4b2f06f87544fa60f60740007e0aa600311"}, - {file = "fonttools-4.56.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc871904a53a9d4d908673c6faa15689874af1c7c5ac403a8e12d967ebd0c0dc"}, - {file = "fonttools-4.56.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:38b947de71748bab150259ee05a775e8a0635891568e9fdb3cdd7d0e0004e62f"}, - {file = "fonttools-4.56.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:86b2a1013ef7a64d2e94606632683f07712045ed86d937c11ef4dde97319c086"}, - {file = "fonttools-4.56.0-cp310-cp310-win32.whl", hash = "sha256:133bedb9a5c6376ad43e6518b7e2cd2f866a05b1998f14842631d5feb36b5786"}, - {file = "fonttools-4.56.0-cp310-cp310-win_amd64.whl", hash = "sha256:17f39313b649037f6c800209984a11fc256a6137cbe5487091c6c7187cae4685"}, - {file = "fonttools-4.56.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7ef04bc7827adb7532be3d14462390dd71287644516af3f1e67f1e6ff9c6d6df"}, - {file = "fonttools-4.56.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ffda9b8cd9cb8b301cae2602ec62375b59e2e2108a117746f12215145e3f786c"}, - {file = "fonttools-4.56.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e993e8db36306cc3f1734edc8ea67906c55f98683d6fd34c3fc5593fdbba4c"}, - {file = "fonttools-4.56.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:003548eadd674175510773f73fb2060bb46adb77c94854af3e0cc5bc70260049"}, - {file = "fonttools-4.56.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bd9825822e7bb243f285013e653f6741954d8147427aaa0324a862cdbf4cbf62"}, - {file = "fonttools-4.56.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b23d30a2c0b992fb1c4f8ac9bfde44b5586d23457759b6cf9a787f1a35179ee0"}, - {file = "fonttools-4.56.0-cp311-cp311-win32.whl", hash = "sha256:47b5e4680002ae1756d3ae3b6114e20aaee6cc5c69d1e5911f5ffffd3ee46c6b"}, - {file = "fonttools-4.56.0-cp311-cp311-win_amd64.whl", hash = "sha256:14a3e3e6b211660db54ca1ef7006401e4a694e53ffd4553ab9bc87ead01d0f05"}, - {file = "fonttools-4.56.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d6f195c14c01bd057bc9b4f70756b510e009c83c5ea67b25ced3e2c38e6ee6e9"}, - {file = "fonttools-4.56.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fa760e5fe8b50cbc2d71884a1eff2ed2b95a005f02dda2fa431560db0ddd927f"}, - {file = "fonttools-4.56.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d54a45d30251f1d729e69e5b675f9a08b7da413391a1227781e2a297fa37f6d2"}, - {file = "fonttools-4.56.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:661a8995d11e6e4914a44ca7d52d1286e2d9b154f685a4d1f69add8418961563"}, - {file = "fonttools-4.56.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9d94449ad0a5f2a8bf5d2f8d71d65088aee48adbe45f3c5f8e00e3ad861ed81a"}, - {file = "fonttools-4.56.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f59746f7953f69cc3290ce2f971ab01056e55ddd0fb8b792c31a8acd7fee2d28"}, - {file = "fonttools-4.56.0-cp312-cp312-win32.whl", hash = "sha256:bce60f9a977c9d3d51de475af3f3581d9b36952e1f8fc19a1f2254f1dda7ce9c"}, - {file = "fonttools-4.56.0-cp312-cp312-win_amd64.whl", hash = "sha256:300c310bb725b2bdb4f5fc7e148e190bd69f01925c7ab437b9c0ca3e1c7cd9ba"}, - {file = "fonttools-4.56.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f20e2c0dfab82983a90f3d00703ac0960412036153e5023eed2b4641d7d5e692"}, - {file = "fonttools-4.56.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f36a0868f47b7566237640c026c65a86d09a3d9ca5df1cd039e30a1da73098a0"}, - {file = "fonttools-4.56.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62b4c6802fa28e14dba010e75190e0e6228513573f1eeae57b11aa1a39b7e5b1"}, - {file = "fonttools-4.56.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a05d1f07eb0a7d755fbe01fee1fd255c3a4d3730130cf1bfefb682d18fd2fcea"}, - {file = "fonttools-4.56.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0073b62c3438cf0058488c002ea90489e8801d3a7af5ce5f7c05c105bee815c3"}, - {file = "fonttools-4.56.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e2cad98c94833465bcf28f51c248aaf07ca022efc6a3eba750ad9c1e0256d278"}, - {file = "fonttools-4.56.0-cp313-cp313-win32.whl", hash = "sha256:d0cb73ccf7f6d7ca8d0bc7ea8ac0a5b84969a41c56ac3ac3422a24df2680546f"}, - {file = "fonttools-4.56.0-cp313-cp313-win_amd64.whl", hash = "sha256:62cc1253827d1e500fde9dbe981219fea4eb000fd63402283472d38e7d8aa1c6"}, - {file = "fonttools-4.56.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3fd3fccb7b9adaaecfa79ad51b759f2123e1aba97f857936ce044d4f029abd71"}, - {file = "fonttools-4.56.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:193b86e9f769320bc98ffdb42accafb5d0c8c49bd62884f1c0702bc598b3f0a2"}, - {file = "fonttools-4.56.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e81c1cc80c1d8bf071356cc3e0e25071fbba1c75afc48d41b26048980b3c771"}, - {file = "fonttools-4.56.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9270505a19361e81eecdbc2c251ad1e1a9a9c2ad75fa022ccdee533f55535dc"}, - {file = "fonttools-4.56.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:53f5e9767978a4daf46f28e09dbeb7d010319924ae622f7b56174b777258e5ba"}, - {file = "fonttools-4.56.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:9da650cb29bc098b8cfd15ef09009c914b35c7986c8fa9f08b51108b7bc393b4"}, - {file = "fonttools-4.56.0-cp38-cp38-win32.whl", hash = "sha256:965d0209e6dbdb9416100123b6709cb13f5232e2d52d17ed37f9df0cc31e2b35"}, - {file = "fonttools-4.56.0-cp38-cp38-win_amd64.whl", hash = "sha256:654ac4583e2d7c62aebc6fc6a4c6736f078f50300e18aa105d87ce8925cfac31"}, - {file = "fonttools-4.56.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ca7962e8e5fc047cc4e59389959843aafbf7445b6c08c20d883e60ced46370a5"}, - {file = "fonttools-4.56.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a1af375734018951c31c0737d04a9d5fd0a353a0253db5fbed2ccd44eac62d8c"}, - {file = "fonttools-4.56.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:442ad4122468d0e47d83bc59d0e91b474593a8c813839e1872e47c7a0cb53b10"}, - {file = "fonttools-4.56.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cf4f8d2a30b454ac682e12c61831dcb174950c406011418e739de592bbf8f76"}, - {file = "fonttools-4.56.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:96a4271f63a615bcb902b9f56de00ea225d6896052c49f20d0c91e9f43529a29"}, - {file = "fonttools-4.56.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6c1d38642ca2dddc7ae992ef5d026e5061a84f10ff2b906be5680ab089f55bb8"}, - {file = "fonttools-4.56.0-cp39-cp39-win32.whl", hash = "sha256:2d351275f73ebdd81dd5b09a8b8dac7a30f29a279d41e1c1192aedf1b6dced40"}, - {file = "fonttools-4.56.0-cp39-cp39-win_amd64.whl", hash = "sha256:d6ca96d1b61a707ba01a43318c9c40aaf11a5a568d1e61146fafa6ab20890793"}, - {file = "fonttools-4.56.0-py3-none-any.whl", hash = "sha256:1088182f68c303b50ca4dc0c82d42083d176cba37af1937e1a976a31149d4d14"}, - {file = "fonttools-4.56.0.tar.gz", hash = "sha256:a114d1567e1a1586b7e9e7fc2ff686ca542a82769a296cef131e4c4af51e58f4"}, + {file = "fonttools-4.61.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7c7db70d57e5e1089a274cbb2b1fd635c9a24de809a231b154965d415d6c6d24"}, + {file = "fonttools-4.61.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5fe9fd43882620017add5eabb781ebfbc6998ee49b35bd7f8f79af1f9f99a958"}, + {file = "fonttools-4.61.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8db08051fc9e7d8bc622f2112511b8107d8f27cd89e2f64ec45e9825e8288da"}, + {file = "fonttools-4.61.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a76d4cb80f41ba94a6691264be76435e5f72f2cb3cab0b092a6212855f71c2f6"}, + {file = "fonttools-4.61.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a13fc8aeb24bad755eea8f7f9d409438eb94e82cf86b08fe77a03fbc8f6a96b1"}, + {file = "fonttools-4.61.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b846a1fcf8beadeb9ea4f44ec5bdde393e2f1569e17d700bfc49cd69bde75881"}, + {file = "fonttools-4.61.1-cp310-cp310-win32.whl", hash = "sha256:78a7d3ab09dc47ac1a363a493e6112d8cabed7ba7caad5f54dbe2f08676d1b47"}, + {file = "fonttools-4.61.1-cp310-cp310-win_amd64.whl", hash = "sha256:eff1ac3cc66c2ac7cda1e64b4e2f3ffef474b7335f92fc3833fc632d595fcee6"}, + {file = "fonttools-4.61.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c6604b735bb12fef8e0efd5578c9fb5d3d8532d5001ea13a19cddf295673ee09"}, + {file = "fonttools-4.61.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5ce02f38a754f207f2f06557523cd39a06438ba3aafc0639c477ac409fc64e37"}, + {file = "fonttools-4.61.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:77efb033d8d7ff233385f30c62c7c79271c8885d5c9657d967ede124671bbdfb"}, + {file = "fonttools-4.61.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:75c1a6dfac6abd407634420c93864a1e274ebc1c7531346d9254c0d8f6ca00f9"}, + {file = "fonttools-4.61.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0de30bfe7745c0d1ffa2b0b7048fb7123ad0d71107e10ee090fa0b16b9452e87"}, + {file = "fonttools-4.61.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:58b0ee0ab5b1fc9921eccfe11d1435added19d6494dde14e323f25ad2bc30c56"}, + {file = "fonttools-4.61.1-cp311-cp311-win32.whl", hash = "sha256:f79b168428351d11e10c5aeb61a74e1851ec221081299f4cf56036a95431c43a"}, + {file = "fonttools-4.61.1-cp311-cp311-win_amd64.whl", hash = "sha256:fe2efccb324948a11dd09d22136fe2ac8a97d6c1347cf0b58a911dcd529f66b7"}, + {file = "fonttools-4.61.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f3cb4a569029b9f291f88aafc927dd53683757e640081ca8c412781ea144565e"}, + {file = "fonttools-4.61.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41a7170d042e8c0024703ed13b71893519a1a6d6e18e933e3ec7507a2c26a4b2"}, + {file = "fonttools-4.61.1-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:10d88e55330e092940584774ee5e8a6971b01fc2f4d3466a1d6c158230880796"}, + {file = "fonttools-4.61.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:15acc09befd16a0fb8a8f62bc147e1a82817542d72184acca9ce6e0aeda9fa6d"}, + {file = "fonttools-4.61.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e6bcdf33aec38d16508ce61fd81838f24c83c90a1d1b8c68982857038673d6b8"}, + {file = "fonttools-4.61.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5fade934607a523614726119164ff621e8c30e8fa1ffffbbd358662056ba69f0"}, + {file = "fonttools-4.61.1-cp312-cp312-win32.whl", hash = "sha256:75da8f28eff26defba42c52986de97b22106cb8f26515b7c22443ebc9c2d3261"}, + {file = "fonttools-4.61.1-cp312-cp312-win_amd64.whl", hash = "sha256:497c31ce314219888c0e2fce5ad9178ca83fe5230b01a5006726cdf3ac9f24d9"}, + {file = "fonttools-4.61.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8c56c488ab471628ff3bfa80964372fc13504ece601e0d97a78ee74126b2045c"}, + {file = "fonttools-4.61.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dc492779501fa723b04d0ab1f5be046797fee17d27700476edc7ee9ae535a61e"}, + {file = "fonttools-4.61.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:64102ca87e84261419c3747a0d20f396eb024bdbeb04c2bfb37e2891f5fadcb5"}, + {file = "fonttools-4.61.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c1b526c8d3f615a7b1867f38a9410849c8f4aef078535742198e942fba0e9bd"}, + {file = "fonttools-4.61.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:41ed4b5ec103bd306bb68f81dc166e77409e5209443e5773cb4ed837bcc9b0d3"}, + {file = "fonttools-4.61.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b501c862d4901792adaec7c25b1ecc749e2662543f68bb194c42ba18d6eec98d"}, + {file = "fonttools-4.61.1-cp313-cp313-win32.whl", hash = "sha256:4d7092bb38c53bbc78e9255a59158b150bcdc115a1e3b3ce0b5f267dc35dd63c"}, + {file = "fonttools-4.61.1-cp313-cp313-win_amd64.whl", hash = "sha256:21e7c8d76f62ab13c9472ccf74515ca5b9a761d1bde3265152a6dc58700d895b"}, + {file = "fonttools-4.61.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:fff4f534200a04b4a36e7ae3cb74493afe807b517a09e99cb4faa89a34ed6ecd"}, + {file = "fonttools-4.61.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d9203500f7c63545b4ce3799319fe4d9feb1a1b89b28d3cb5abd11b9dd64147e"}, + {file = "fonttools-4.61.1-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fa646ecec9528bef693415c79a86e733c70a4965dd938e9a226b0fc64c9d2e6c"}, + {file = "fonttools-4.61.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:11f35ad7805edba3aac1a3710d104592df59f4b957e30108ae0ba6c10b11dd75"}, + {file = "fonttools-4.61.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b931ae8f62db78861b0ff1ac017851764602288575d65b8e8ff1963fed419063"}, + {file = "fonttools-4.61.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b148b56f5de675ee16d45e769e69f87623a4944f7443850bf9a9376e628a89d2"}, + {file = "fonttools-4.61.1-cp314-cp314-win32.whl", hash = "sha256:9b666a475a65f4e839d3d10473fad6d47e0a9db14a2f4a224029c5bfde58ad2c"}, + {file = "fonttools-4.61.1-cp314-cp314-win_amd64.whl", hash = "sha256:4f5686e1fe5fce75d82d93c47a438a25bf0d1319d2843a926f741140b2b16e0c"}, + {file = "fonttools-4.61.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:e76ce097e3c57c4bcb67c5aa24a0ecdbd9f74ea9219997a707a4061fbe2707aa"}, + {file = "fonttools-4.61.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:9cfef3ab326780c04d6646f68d4b4742aae222e8b8ea1d627c74e38afcbc9d91"}, + {file = "fonttools-4.61.1-cp314-cp314t-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a75c301f96db737e1c5ed5fd7d77d9c34466de16095a266509e13da09751bd19"}, + {file = "fonttools-4.61.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:91669ccac46bbc1d09e9273546181919064e8df73488ea087dcac3e2968df9ba"}, + {file = "fonttools-4.61.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c33ab3ca9d3ccd581d58e989d67554e42d8d4ded94ab3ade3508455fe70e65f7"}, + {file = "fonttools-4.61.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:664c5a68ec406f6b1547946683008576ef8b38275608e1cee6c061828171c118"}, + {file = "fonttools-4.61.1-cp314-cp314t-win32.whl", hash = "sha256:aed04cabe26f30c1647ef0e8fbb207516fd40fe9472e9439695f5c6998e60ac5"}, + {file = "fonttools-4.61.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2180f14c141d2f0f3da43f3a81bc8aa4684860f6b0e6f9e165a4831f24e6a23b"}, + {file = "fonttools-4.61.1-py3-none-any.whl", hash = "sha256:17d2bf5d541add43822bcf0c43d7d847b160c9bb01d15d5007d84e2217aaa371"}, + {file = "fonttools-4.61.1.tar.gz", hash = "sha256:6675329885c44657f826ef01d9e4fb33b9158e9d93c537d84ad8399539bc6f69"}, ] [package.extras] -all = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "fs (>=2.2.0,<3)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\"", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.23.0)", "unicodedata2 (>=15.1.0) ; python_version <= \"3.12\"", "xattr ; sys_platform == \"darwin\"", "zopfli (>=0.1.4)"] +all = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\"", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.45.0)", "unicodedata2 (>=17.0.0) ; python_version <= \"3.14\"", "xattr ; sys_platform == \"darwin\"", "zopfli (>=0.1.4)"] graphite = ["lz4 (>=1.7.4.2)"] interpolatable = ["munkres ; platform_python_implementation == \"PyPy\"", "pycairo", "scipy ; platform_python_implementation != \"PyPy\""] lxml = ["lxml (>=4.0)"] pathops = ["skia-pathops (>=0.5.0)"] plot = ["matplotlib"] -repacker = ["uharfbuzz (>=0.23.0)"] +repacker = ["uharfbuzz (>=0.45.0)"] symfont = ["sympy"] type1 = ["xattr ; sys_platform == \"darwin\""] -ufo = ["fs (>=2.2.0,<3)"] -unicode = ["unicodedata2 (>=15.1.0) ; python_version <= \"3.12\""] +unicode = ["unicodedata2 (>=17.0.0) ; python_version <= \"3.14\""] woff = ["brotli (>=1.0.1) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\"", "zopfli (>=0.1.4)"] [[package]] name = "gunicorn" -version = "23.0.0" +version = "25.1.0" description = "WSGI HTTP Server for UNIX" optional = false -python-versions = ">=3.7" +python-versions = ">=3.10" groups = ["main"] files = [ - {file = "gunicorn-23.0.0-py3-none-any.whl", hash = "sha256:ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d"}, - {file = "gunicorn-23.0.0.tar.gz", hash = "sha256:f014447a0101dc57e294f6c18ca6b40227a4c90e9bdb586042628030cba004ec"}, + {file = "gunicorn-25.1.0-py3-none-any.whl", hash = "sha256:d0b1236ccf27f72cfe14bce7caadf467186f19e865094ca84221424e839b8b8b"}, + {file = "gunicorn-25.1.0.tar.gz", hash = "sha256:1426611d959fa77e7de89f8c0f32eed6aa03ee735f98c01efba3e281b1c47616"}, ] [package.dependencies] packaging = "*" [package.extras] -eventlet = ["eventlet (>=0.24.1,!=0.36.0)"] -gevent = ["gevent (>=1.4.0)"] +eventlet = ["eventlet (>=0.40.3)"] +gevent = ["gevent (>=24.10.1)"] +http2 = ["h2 (>=4.1.0)"] setproctitle = ["setproctitle"] -testing = ["coverage", "eventlet", "gevent", "pytest", "pytest-cov"] -tornado = ["tornado (>=0.2)"] +testing = ["coverage", "eventlet (>=0.40.3)", "gevent (>=24.10.1)", "h2 (>=4.1.0)", "httpx[http2]", "pytest", "pytest-asyncio", "pytest-cov", "uvloop (>=0.19.0)"] +tornado = ["tornado (>=6.5.0)"] [[package]] name = "idna" @@ -782,6 +938,30 @@ files = [ [package.extras] all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] +[[package]] +name = "importlib-metadata" +version = "8.5.0" +description = "Read metadata from Python packages" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "importlib_metadata-8.5.0-py3-none-any.whl", hash = "sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b"}, + {file = "importlib_metadata-8.5.0.tar.gz", hash = "sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7"}, +] + +[package.dependencies] +zipp = ">=3.20" + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +perf = ["ipython"] +test = ["flufl.flake8", "importlib-resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-perf (>=0.9.2)"] +type = ["pytest-mypy"] + [[package]] name = "iniconfig" version = "2.0.0" @@ -820,14 +1000,14 @@ files = [ [[package]] name = "jinja2" -version = "3.1.5" +version = "3.1.6" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" groups = ["main"] files = [ - {file = "jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb"}, - {file = "jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb"}, + {file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"}, + {file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"}, ] [package.dependencies] @@ -838,92 +1018,113 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "kiwisolver" -version = "1.4.8" +version = "1.4.9" description = "A fast implementation of the Cassowary constraint solver" optional = false python-versions = ">=3.10" groups = ["main"] files = [ - {file = "kiwisolver-1.4.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88c6f252f6816a73b1f8c904f7bbe02fd67c09a69f7cb8a0eecdbf5ce78e63db"}, - {file = "kiwisolver-1.4.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c72941acb7b67138f35b879bbe85be0f6c6a70cab78fe3ef6db9c024d9223e5b"}, - {file = "kiwisolver-1.4.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ce2cf1e5688edcb727fdf7cd1bbd0b6416758996826a8be1d958f91880d0809d"}, - {file = "kiwisolver-1.4.8-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c8bf637892dc6e6aad2bc6d4d69d08764166e5e3f69d469e55427b6ac001b19d"}, - {file = "kiwisolver-1.4.8-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:034d2c891f76bd3edbdb3ea11140d8510dca675443da7304205a2eaa45d8334c"}, - {file = "kiwisolver-1.4.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d47b28d1dfe0793d5e96bce90835e17edf9a499b53969b03c6c47ea5985844c3"}, - {file = "kiwisolver-1.4.8-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb158fe28ca0c29f2260cca8c43005329ad58452c36f0edf298204de32a9a3ed"}, - {file = "kiwisolver-1.4.8-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5536185fce131780ebd809f8e623bf4030ce1b161353166c49a3c74c287897f"}, - {file = "kiwisolver-1.4.8-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:369b75d40abedc1da2c1f4de13f3482cb99e3237b38726710f4a793432b1c5ff"}, - {file = "kiwisolver-1.4.8-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:641f2ddf9358c80faa22e22eb4c9f54bd3f0e442e038728f500e3b978d00aa7d"}, - {file = "kiwisolver-1.4.8-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d561d2d8883e0819445cfe58d7ddd673e4015c3c57261d7bdcd3710d0d14005c"}, - {file = "kiwisolver-1.4.8-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:1732e065704b47c9afca7ffa272f845300a4eb959276bf6970dc07265e73b605"}, - {file = "kiwisolver-1.4.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bcb1ebc3547619c3b58a39e2448af089ea2ef44b37988caf432447374941574e"}, - {file = "kiwisolver-1.4.8-cp310-cp310-win_amd64.whl", hash = "sha256:89c107041f7b27844179ea9c85d6da275aa55ecf28413e87624d033cf1f6b751"}, - {file = "kiwisolver-1.4.8-cp310-cp310-win_arm64.whl", hash = "sha256:b5773efa2be9eb9fcf5415ea3ab70fc785d598729fd6057bea38d539ead28271"}, - {file = "kiwisolver-1.4.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a4d3601908c560bdf880f07d94f31d734afd1bb71e96585cace0e38ef44c6d84"}, - {file = "kiwisolver-1.4.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:856b269c4d28a5c0d5e6c1955ec36ebfd1651ac00e1ce0afa3e28da95293b561"}, - {file = "kiwisolver-1.4.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c2b9a96e0f326205af81a15718a9073328df1173a2619a68553decb7097fd5d7"}, - {file = "kiwisolver-1.4.8-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5020c83e8553f770cb3b5fc13faac40f17e0b205bd237aebd21d53d733adb03"}, - {file = "kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dace81d28c787956bfbfbbfd72fdcef014f37d9b48830829e488fdb32b49d954"}, - {file = "kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11e1022b524bd48ae56c9b4f9296bce77e15a2e42a502cceba602f804b32bb79"}, - {file = "kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b9b4d2892fefc886f30301cdd80debd8bb01ecdf165a449eb6e78f79f0fabd6"}, - {file = "kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a96c0e790ee875d65e340ab383700e2b4891677b7fcd30a699146f9384a2bb0"}, - {file = "kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:23454ff084b07ac54ca8be535f4174170c1094a4cff78fbae4f73a4bcc0d4dab"}, - {file = "kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:87b287251ad6488e95b4f0b4a79a6d04d3ea35fde6340eb38fbd1ca9cd35bbbc"}, - {file = "kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b21dbe165081142b1232a240fc6383fd32cdd877ca6cc89eab93e5f5883e1c25"}, - {file = "kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:768cade2c2df13db52475bd28d3a3fac8c9eff04b0e9e2fda0f3760f20b3f7fc"}, - {file = "kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d47cfb2650f0e103d4bf68b0b5804c68da97272c84bb12850d877a95c056bd67"}, - {file = "kiwisolver-1.4.8-cp311-cp311-win_amd64.whl", hash = "sha256:ed33ca2002a779a2e20eeb06aea7721b6e47f2d4b8a8ece979d8ba9e2a167e34"}, - {file = "kiwisolver-1.4.8-cp311-cp311-win_arm64.whl", hash = "sha256:16523b40aab60426ffdebe33ac374457cf62863e330a90a0383639ce14bf44b2"}, - {file = "kiwisolver-1.4.8-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d6af5e8815fd02997cb6ad9bbed0ee1e60014438ee1a5c2444c96f87b8843502"}, - {file = "kiwisolver-1.4.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bade438f86e21d91e0cf5dd7c0ed00cda0f77c8c1616bd83f9fc157fa6760d31"}, - {file = "kiwisolver-1.4.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b83dc6769ddbc57613280118fb4ce3cd08899cc3369f7d0e0fab518a7cf37fdb"}, - {file = "kiwisolver-1.4.8-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:111793b232842991be367ed828076b03d96202c19221b5ebab421ce8bcad016f"}, - {file = "kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:257af1622860e51b1a9d0ce387bf5c2c4f36a90594cb9514f55b074bcc787cfc"}, - {file = "kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:69b5637c3f316cab1ec1c9a12b8c5f4750a4c4b71af9157645bf32830e39c03a"}, - {file = "kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:782bb86f245ec18009890e7cb8d13a5ef54dcf2ebe18ed65f795e635a96a1c6a"}, - {file = "kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc978a80a0db3a66d25767b03688f1147a69e6237175c0f4ffffaaedf744055a"}, - {file = "kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:36dbbfd34838500a31f52c9786990d00150860e46cd5041386f217101350f0d3"}, - {file = "kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:eaa973f1e05131de5ff3569bbba7f5fd07ea0595d3870ed4a526d486fe57fa1b"}, - {file = "kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:a66f60f8d0c87ab7f59b6fb80e642ebb29fec354a4dfad687ca4092ae69d04f4"}, - {file = "kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:858416b7fb777a53f0c59ca08190ce24e9abbd3cffa18886a5781b8e3e26f65d"}, - {file = "kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:085940635c62697391baafaaeabdf3dd7a6c3643577dde337f4d66eba021b2b8"}, - {file = "kiwisolver-1.4.8-cp312-cp312-win_amd64.whl", hash = "sha256:01c3d31902c7db5fb6182832713d3b4122ad9317c2c5877d0539227d96bb2e50"}, - {file = "kiwisolver-1.4.8-cp312-cp312-win_arm64.whl", hash = "sha256:a3c44cb68861de93f0c4a8175fbaa691f0aa22550c331fefef02b618a9dcb476"}, - {file = "kiwisolver-1.4.8-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:1c8ceb754339793c24aee1c9fb2485b5b1f5bb1c2c214ff13368431e51fc9a09"}, - {file = "kiwisolver-1.4.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:54a62808ac74b5e55a04a408cda6156f986cefbcf0ada13572696b507cc92fa1"}, - {file = "kiwisolver-1.4.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:68269e60ee4929893aad82666821aaacbd455284124817af45c11e50a4b42e3c"}, - {file = "kiwisolver-1.4.8-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34d142fba9c464bc3bbfeff15c96eab0e7310343d6aefb62a79d51421fcc5f1b"}, - {file = "kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ddc373e0eef45b59197de815b1b28ef89ae3955e7722cc9710fb91cd77b7f47"}, - {file = "kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:77e6f57a20b9bd4e1e2cedda4d0b986ebd0216236f0106e55c28aea3d3d69b16"}, - {file = "kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08e77738ed7538f036cd1170cbed942ef749137b1311fa2bbe2a7fda2f6bf3cc"}, - {file = "kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5ce1e481a74b44dd5e92ff03ea0cb371ae7a0268318e202be06c8f04f4f1246"}, - {file = "kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:fc2ace710ba7c1dfd1a3b42530b62b9ceed115f19a1656adefce7b1782a37794"}, - {file = "kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:3452046c37c7692bd52b0e752b87954ef86ee2224e624ef7ce6cb21e8c41cc1b"}, - {file = "kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7e9a60b50fe8b2ec6f448fe8d81b07e40141bfced7f896309df271a0b92f80f3"}, - {file = "kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:918139571133f366e8362fa4a297aeba86c7816b7ecf0bc79168080e2bd79957"}, - {file = "kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e063ef9f89885a1d68dd8b2e18f5ead48653176d10a0e324e3b0030e3a69adeb"}, - {file = "kiwisolver-1.4.8-cp313-cp313-win_amd64.whl", hash = "sha256:a17b7c4f5b2c51bb68ed379defd608a03954a1845dfed7cc0117f1cc8a9b7fd2"}, - {file = "kiwisolver-1.4.8-cp313-cp313-win_arm64.whl", hash = "sha256:3cd3bc628b25f74aedc6d374d5babf0166a92ff1317f46267f12d2ed54bc1d30"}, - {file = "kiwisolver-1.4.8-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:370fd2df41660ed4e26b8c9d6bbcad668fbe2560462cba151a721d49e5b6628c"}, - {file = "kiwisolver-1.4.8-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:84a2f830d42707de1d191b9490ac186bf7997a9495d4e9072210a1296345f7dc"}, - {file = "kiwisolver-1.4.8-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:7a3ad337add5148cf51ce0b55642dc551c0b9d6248458a757f98796ca7348712"}, - {file = "kiwisolver-1.4.8-cp313-cp313t-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7506488470f41169b86d8c9aeff587293f530a23a23a49d6bc64dab66bedc71e"}, - {file = "kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f0121b07b356a22fb0414cec4666bbe36fd6d0d759db3d37228f496ed67c880"}, - {file = "kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d6d6bd87df62c27d4185de7c511c6248040afae67028a8a22012b010bc7ad062"}, - {file = "kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:291331973c64bb9cce50bbe871fb2e675c4331dab4f31abe89f175ad7679a4d7"}, - {file = "kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:893f5525bb92d3d735878ec00f781b2de998333659507d29ea4466208df37bed"}, - {file = "kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b47a465040146981dc9db8647981b8cb96366fbc8d452b031e4f8fdffec3f26d"}, - {file = "kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:99cea8b9dd34ff80c521aef46a1dddb0dcc0283cf18bde6d756f1e6f31772165"}, - {file = "kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:151dffc4865e5fe6dafce5480fab84f950d14566c480c08a53c663a0020504b6"}, - {file = "kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:577facaa411c10421314598b50413aa1ebcf5126f704f1e5d72d7e4e9f020d90"}, - {file = "kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:be4816dc51c8a471749d664161b434912eee82f2ea66bd7628bd14583a833e85"}, - {file = "kiwisolver-1.4.8-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:e7a019419b7b510f0f7c9dceff8c5eae2392037eae483a7f9162625233802b0a"}, - {file = "kiwisolver-1.4.8-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:286b18e86682fd2217a48fc6be6b0f20c1d0ed10958d8dc53453ad58d7be0bf8"}, - {file = "kiwisolver-1.4.8-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4191ee8dfd0be1c3666ccbac178c5a05d5f8d689bbe3fc92f3c4abec817f8fe0"}, - {file = "kiwisolver-1.4.8-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7cd2785b9391f2873ad46088ed7599a6a71e762e1ea33e87514b1a441ed1da1c"}, - {file = "kiwisolver-1.4.8-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c07b29089b7ba090b6f1a669f1411f27221c3662b3a1b7010e67b59bb5a6f10b"}, - {file = "kiwisolver-1.4.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:65ea09a5a3faadd59c2ce96dc7bf0f364986a315949dc6374f04396b0d60e09b"}, - {file = "kiwisolver-1.4.8.tar.gz", hash = "sha256:23d5f023bdc8c7e54eb65f03ca5d5bb25b601eac4d7f1a042888a1f45237987e"}, + {file = "kiwisolver-1.4.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b4b4d74bda2b8ebf4da5bd42af11d02d04428b2c32846e4c2c93219df8a7987b"}, + {file = "kiwisolver-1.4.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fb3b8132019ea572f4611d770991000d7f58127560c4889729248eb5852a102f"}, + {file = "kiwisolver-1.4.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:84fd60810829c27ae375114cd379da1fa65e6918e1da405f356a775d49a62bcf"}, + {file = "kiwisolver-1.4.9-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b78efa4c6e804ecdf727e580dbb9cba85624d2e1c6b5cb059c66290063bd99a9"}, + {file = "kiwisolver-1.4.9-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d4efec7bcf21671db6a3294ff301d2fc861c31faa3c8740d1a94689234d1b415"}, + {file = "kiwisolver-1.4.9-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:90f47e70293fc3688b71271100a1a5453aa9944a81d27ff779c108372cf5567b"}, + {file = "kiwisolver-1.4.9-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8fdca1def57a2e88ef339de1737a1449d6dbf5fab184c54a1fca01d541317154"}, + {file = "kiwisolver-1.4.9-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9cf554f21be770f5111a1690d42313e140355e687e05cf82cb23d0a721a64a48"}, + {file = "kiwisolver-1.4.9-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fc1795ac5cd0510207482c3d1d3ed781143383b8cfd36f5c645f3897ce066220"}, + {file = "kiwisolver-1.4.9-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:ccd09f20ccdbbd341b21a67ab50a119b64a403b09288c27481575105283c1586"}, + {file = "kiwisolver-1.4.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:540c7c72324d864406a009d72f5d6856f49693db95d1fbb46cf86febef873634"}, + {file = "kiwisolver-1.4.9-cp310-cp310-win_amd64.whl", hash = "sha256:ede8c6d533bc6601a47ad4046080d36b8fc99f81e6f1c17b0ac3c2dc91ac7611"}, + {file = "kiwisolver-1.4.9-cp310-cp310-win_arm64.whl", hash = "sha256:7b4da0d01ac866a57dd61ac258c5607b4cd677f63abaec7b148354d2b2cdd536"}, + {file = "kiwisolver-1.4.9-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eb14a5da6dc7642b0f3a18f13654847cd8b7a2550e2645a5bda677862b03ba16"}, + {file = "kiwisolver-1.4.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:39a219e1c81ae3b103643d2aedb90f1ef22650deb266ff12a19e7773f3e5f089"}, + {file = "kiwisolver-1.4.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2405a7d98604b87f3fc28b1716783534b1b4b8510d8142adca34ee0bc3c87543"}, + {file = "kiwisolver-1.4.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:dc1ae486f9abcef254b5618dfb4113dd49f94c68e3e027d03cf0143f3f772b61"}, + {file = "kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a1f570ce4d62d718dce3f179ee78dac3b545ac16c0c04bb363b7607a949c0d1"}, + {file = "kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb27e7b78d716c591e88e0a09a2139c6577865d7f2e152488c2cc6257f460872"}, + {file = "kiwisolver-1.4.9-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:15163165efc2f627eb9687ea5f3a28137217d217ac4024893d753f46bce9de26"}, + {file = "kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bdee92c56a71d2b24c33a7d4c2856bd6419d017e08caa7802d2963870e315028"}, + {file = "kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:412f287c55a6f54b0650bd9b6dce5aceddb95864a1a90c87af16979d37c89771"}, + {file = "kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2c93f00dcba2eea70af2be5f11a830a742fe6b579a1d4e00f47760ef13be247a"}, + {file = "kiwisolver-1.4.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f117e1a089d9411663a3207ba874f31be9ac8eaa5b533787024dc07aeb74f464"}, + {file = "kiwisolver-1.4.9-cp311-cp311-win_amd64.whl", hash = "sha256:be6a04e6c79819c9a8c2373317d19a96048e5a3f90bec587787e86a1153883c2"}, + {file = "kiwisolver-1.4.9-cp311-cp311-win_arm64.whl", hash = "sha256:0ae37737256ba2de764ddc12aed4956460277f00c4996d51a197e72f62f5eec7"}, + {file = "kiwisolver-1.4.9-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ac5a486ac389dddcc5bef4f365b6ae3ffff2c433324fb38dd35e3fab7c957999"}, + {file = "kiwisolver-1.4.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f2ba92255faa7309d06fe44c3a4a97efe1c8d640c2a79a5ef728b685762a6fd2"}, + {file = "kiwisolver-1.4.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a2899935e724dd1074cb568ce7ac0dce28b2cd6ab539c8e001a8578eb106d14"}, + {file = "kiwisolver-1.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f6008a4919fdbc0b0097089f67a1eb55d950ed7e90ce2cc3e640abadd2757a04"}, + {file = "kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:67bb8b474b4181770f926f7b7d2f8c0248cbcb78b660fdd41a47054b28d2a752"}, + {file = "kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2327a4a30d3ee07d2fbe2e7933e8a37c591663b96ce42a00bc67461a87d7df77"}, + {file = "kiwisolver-1.4.9-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7a08b491ec91b1d5053ac177afe5290adacf1f0f6307d771ccac5de30592d198"}, + {file = "kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d8fc5c867c22b828001b6a38d2eaeb88160bf5783c6cb4a5e440efc981ce286d"}, + {file = "kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:3b3115b2581ea35bb6d1f24a4c90af37e5d9b49dcff267eeed14c3893c5b86ab"}, + {file = "kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:858e4c22fb075920b96a291928cb7dea5644e94c0ee4fcd5af7e865655e4ccf2"}, + {file = "kiwisolver-1.4.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ed0fecd28cc62c54b262e3736f8bb2512d8dcfdc2bcf08be5f47f96bf405b145"}, + {file = "kiwisolver-1.4.9-cp312-cp312-win_amd64.whl", hash = "sha256:f68208a520c3d86ea51acf688a3e3002615a7f0238002cccc17affecc86a8a54"}, + {file = "kiwisolver-1.4.9-cp312-cp312-win_arm64.whl", hash = "sha256:2c1a4f57df73965f3f14df20b80ee29e6a7930a57d2d9e8491a25f676e197c60"}, + {file = "kiwisolver-1.4.9-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a5d0432ccf1c7ab14f9949eec60c5d1f924f17c037e9f8b33352fa05799359b8"}, + {file = "kiwisolver-1.4.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efb3a45b35622bb6c16dbfab491a8f5a391fe0e9d45ef32f4df85658232ca0e2"}, + {file = "kiwisolver-1.4.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1a12cf6398e8a0a001a059747a1cbf24705e18fe413bc22de7b3d15c67cffe3f"}, + {file = "kiwisolver-1.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b67e6efbf68e077dd71d1a6b37e43e1a99d0bff1a3d51867d45ee8908b931098"}, + {file = "kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5656aa670507437af0207645273ccdfee4f14bacd7f7c67a4306d0dcaeaf6eed"}, + {file = "kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bfc08add558155345129c7803b3671cf195e6a56e7a12f3dde7c57d9b417f525"}, + {file = "kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:40092754720b174e6ccf9e845d0d8c7d8e12c3d71e7fc35f55f3813e96376f78"}, + {file = "kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:497d05f29a1300d14e02e6441cf0f5ee81c1ff5a304b0d9fb77423974684e08b"}, + {file = "kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:bdd1a81a1860476eb41ac4bc1e07b3f07259e6d55bbf739b79c8aaedcf512799"}, + {file = "kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e6b93f13371d341afee3be9f7c5964e3fe61d5fa30f6a30eb49856935dfe4fc3"}, + {file = "kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d75aa530ccfaa593da12834b86a0724f58bff12706659baa9227c2ccaa06264c"}, + {file = "kiwisolver-1.4.9-cp313-cp313-win_amd64.whl", hash = "sha256:dd0a578400839256df88c16abddf9ba14813ec5f21362e1fe65022e00c883d4d"}, + {file = "kiwisolver-1.4.9-cp313-cp313-win_arm64.whl", hash = "sha256:d4188e73af84ca82468f09cadc5ac4db578109e52acb4518d8154698d3a87ca2"}, + {file = "kiwisolver-1.4.9-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:5a0f2724dfd4e3b3ac5a82436a8e6fd16baa7d507117e4279b660fe8ca38a3a1"}, + {file = "kiwisolver-1.4.9-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:1b11d6a633e4ed84fc0ddafd4ebfd8ea49b3f25082c04ad12b8315c11d504dc1"}, + {file = "kiwisolver-1.4.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61874cdb0a36016354853593cffc38e56fc9ca5aa97d2c05d3dcf6922cd55a11"}, + {file = "kiwisolver-1.4.9-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:60c439763a969a6af93b4881db0eed8fadf93ee98e18cbc35bc8da868d0c4f0c"}, + {file = "kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92a2f997387a1b79a75e7803aa7ded2cfbe2823852ccf1ba3bcf613b62ae3197"}, + {file = "kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a31d512c812daea6d8b3be3b2bfcbeb091dbb09177706569bcfc6240dcf8b41c"}, + {file = "kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:52a15b0f35dad39862d376df10c5230155243a2c1a436e39eb55623ccbd68185"}, + {file = "kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a30fd6fdef1430fd9e1ba7b3398b5ee4e2887783917a687d86ba69985fb08748"}, + {file = "kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cc9617b46837c6468197b5945e196ee9ca43057bb7d9d1ae688101e4e1dddf64"}, + {file = "kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:0ab74e19f6a2b027ea4f845a78827969af45ce790e6cb3e1ebab71bdf9f215ff"}, + {file = "kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dba5ee5d3981160c28d5490f0d1b7ed730c22470ff7f6cc26cfcfaacb9896a07"}, + {file = "kiwisolver-1.4.9-cp313-cp313t-win_arm64.whl", hash = "sha256:0749fd8f4218ad2e851e11cc4dc05c7cbc0cbc4267bdfdb31782e65aace4ee9c"}, + {file = "kiwisolver-1.4.9-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:9928fe1eb816d11ae170885a74d074f57af3a0d65777ca47e9aeb854a1fba386"}, + {file = "kiwisolver-1.4.9-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d0005b053977e7b43388ddec89fa567f43d4f6d5c2c0affe57de5ebf290dc552"}, + {file = "kiwisolver-1.4.9-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2635d352d67458b66fd0667c14cb1d4145e9560d503219034a18a87e971ce4f3"}, + {file = "kiwisolver-1.4.9-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:767c23ad1c58c9e827b649a9ab7809fd5fd9db266a9cf02b0e926ddc2c680d58"}, + {file = "kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72d0eb9fba308b8311685c2268cf7d0a0639a6cd027d8128659f72bdd8a024b4"}, + {file = "kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f68e4f3eeca8fb22cc3d731f9715a13b652795ef657a13df1ad0c7dc0e9731df"}, + {file = "kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d84cd4061ae292d8ac367b2c3fa3aad11cb8625a95d135fe93f286f914f3f5a6"}, + {file = "kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a60ea74330b91bd22a29638940d115df9dc00af5035a9a2a6ad9399ffb4ceca5"}, + {file = "kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ce6a3a4e106cf35c2d9c4fa17c05ce0b180db622736845d4315519397a77beaf"}, + {file = "kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:77937e5e2a38a7b48eef0585114fe7930346993a88060d0bf886086d2aa49ef5"}, + {file = "kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:24c175051354f4a28c5d6a31c93906dc653e2bf234e8a4bbfb964892078898ce"}, + {file = "kiwisolver-1.4.9-cp314-cp314-win_amd64.whl", hash = "sha256:0763515d4df10edf6d06a3c19734e2566368980d21ebec439f33f9eb936c07b7"}, + {file = "kiwisolver-1.4.9-cp314-cp314-win_arm64.whl", hash = "sha256:0e4e2bf29574a6a7b7f6cb5fa69293b9f96c928949ac4a53ba3f525dffb87f9c"}, + {file = "kiwisolver-1.4.9-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d976bbb382b202f71c67f77b0ac11244021cfa3f7dfd9e562eefcea2df711548"}, + {file = "kiwisolver-1.4.9-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2489e4e5d7ef9a1c300a5e0196e43d9c739f066ef23270607d45aba368b91f2d"}, + {file = "kiwisolver-1.4.9-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e2ea9f7ab7fbf18fffb1b5434ce7c69a07582f7acc7717720f1d69f3e806f90c"}, + {file = "kiwisolver-1.4.9-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b34e51affded8faee0dfdb705416153819d8ea9250bbbf7ea1b249bdeb5f1122"}, + {file = "kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8aacd3d4b33b772542b2e01beb50187536967b514b00003bdda7589722d2a64"}, + {file = "kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7cf974dd4e35fa315563ac99d6287a1024e4dc2077b8a7d7cd3d2fb65d283134"}, + {file = "kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:85bd218b5ecfbee8c8a82e121802dcb519a86044c9c3b2e4aef02fa05c6da370"}, + {file = "kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0856e241c2d3df4efef7c04a1e46b1936b6120c9bcf36dd216e3acd84bc4fb21"}, + {file = "kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:9af39d6551f97d31a4deebeac6f45b156f9755ddc59c07b402c148f5dbb6482a"}, + {file = "kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:bb4ae2b57fc1d8cbd1cf7b1d9913803681ffa903e7488012be5b76dedf49297f"}, + {file = "kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:aedff62918805fb62d43a4aa2ecd4482c380dc76cd31bd7c8878588a61bd0369"}, + {file = "kiwisolver-1.4.9-cp314-cp314t-win_amd64.whl", hash = "sha256:1fa333e8b2ce4d9660f2cda9c0e1b6bafcfb2457a9d259faa82289e73ec24891"}, + {file = "kiwisolver-1.4.9-cp314-cp314t-win_arm64.whl", hash = "sha256:4a48a2ce79d65d363597ef7b567ce3d14d68783d2b2263d98db3d9477805ba32"}, + {file = "kiwisolver-1.4.9-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:4d1d9e582ad4d63062d34077a9a1e9f3c34088a2ec5135b1f7190c07cf366527"}, + {file = "kiwisolver-1.4.9-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:deed0c7258ceb4c44ad5ec7d9918f9f14fd05b2be86378d86cf50e63d1e7b771"}, + {file = "kiwisolver-1.4.9-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0a590506f303f512dff6b7f75fd2fd18e16943efee932008fe7140e5fa91d80e"}, + {file = "kiwisolver-1.4.9-pp310-pypy310_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e09c2279a4d01f099f52d5c4b3d9e208e91edcbd1a175c9662a8b16e000fece9"}, + {file = "kiwisolver-1.4.9-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c9e7cdf45d594ee04d5be1b24dd9d49f3d1590959b2271fb30b5ca2b262c00fb"}, + {file = "kiwisolver-1.4.9-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:720e05574713db64c356e86732c0f3c5252818d05f9df320f0ad8380641acea5"}, + {file = "kiwisolver-1.4.9-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:17680d737d5335b552994a2008fab4c851bcd7de33094a82067ef3a576ff02fa"}, + {file = "kiwisolver-1.4.9-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:85b5352f94e490c028926ea567fc569c52ec79ce131dadb968d3853e809518c2"}, + {file = "kiwisolver-1.4.9-pp311-pypy311_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:464415881e4801295659462c49461a24fb107c140de781d55518c4b80cb6790f"}, + {file = "kiwisolver-1.4.9-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:fb940820c63a9590d31d88b815e7a3aa5915cad3ce735ab45f0c730b39547de1"}, + {file = "kiwisolver-1.4.9.tar.gz", hash = "sha256:c3b22c26c6fd6811b0ae8363b95ca8ce4ea3c202d3d0975b2914310ceb1bcc4d"}, ] [[package]] @@ -1024,46 +1225,67 @@ files = [ [[package]] name = "matplotlib" -version = "3.10.0" +version = "3.10.8" description = "Python plotting package" optional = false python-versions = ">=3.10" groups = ["main"] files = [ - {file = "matplotlib-3.10.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2c5829a5a1dd5a71f0e31e6e8bb449bc0ee9dbfb05ad28fc0c6b55101b3a4be6"}, - {file = "matplotlib-3.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a2a43cbefe22d653ab34bb55d42384ed30f611bcbdea1f8d7f431011a2e1c62e"}, - {file = "matplotlib-3.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:607b16c8a73943df110f99ee2e940b8a1cbf9714b65307c040d422558397dac5"}, - {file = "matplotlib-3.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01d2b19f13aeec2e759414d3bfe19ddfb16b13a1250add08d46d5ff6f9be83c6"}, - {file = "matplotlib-3.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e6c6461e1fc63df30bf6f80f0b93f5b6784299f721bc28530477acd51bfc3d1"}, - {file = "matplotlib-3.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:994c07b9d9fe8d25951e3202a68c17900679274dadfc1248738dcfa1bd40d7f3"}, - {file = "matplotlib-3.10.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:fd44fc75522f58612ec4a33958a7e5552562b7705b42ef1b4f8c0818e304a363"}, - {file = "matplotlib-3.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c58a9622d5dbeb668f407f35f4e6bfac34bb9ecdcc81680c04d0258169747997"}, - {file = "matplotlib-3.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:845d96568ec873be63f25fa80e9e7fae4be854a66a7e2f0c8ccc99e94a8bd4ef"}, - {file = "matplotlib-3.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5439f4c5a3e2e8eab18e2f8c3ef929772fd5641876db71f08127eed95ab64683"}, - {file = "matplotlib-3.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4673ff67a36152c48ddeaf1135e74ce0d4bce1bbf836ae40ed39c29edf7e2765"}, - {file = "matplotlib-3.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:7e8632baebb058555ac0cde75db885c61f1212e47723d63921879806b40bec6a"}, - {file = "matplotlib-3.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4659665bc7c9b58f8c00317c3c2a299f7f258eeae5a5d56b4c64226fca2f7c59"}, - {file = "matplotlib-3.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d44cb942af1693cced2604c33a9abcef6205601c445f6d0dc531d813af8a2f5a"}, - {file = "matplotlib-3.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a994f29e968ca002b50982b27168addfd65f0105610b6be7fa515ca4b5307c95"}, - {file = "matplotlib-3.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b0558bae37f154fffda54d779a592bc97ca8b4701f1c710055b609a3bac44c8"}, - {file = "matplotlib-3.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:503feb23bd8c8acc75541548a1d709c059b7184cde26314896e10a9f14df5f12"}, - {file = "matplotlib-3.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:c40ba2eb08b3f5de88152c2333c58cee7edcead0a2a0d60fcafa116b17117adc"}, - {file = "matplotlib-3.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96f2886f5c1e466f21cc41b70c5a0cd47bfa0015eb2d5793c88ebce658600e25"}, - {file = "matplotlib-3.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:12eaf48463b472c3c0f8dbacdbf906e573013df81a0ab82f0616ea4b11281908"}, - {file = "matplotlib-3.10.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fbbabc82fde51391c4da5006f965e36d86d95f6ee83fb594b279564a4c5d0d2"}, - {file = "matplotlib-3.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad2e15300530c1a94c63cfa546e3b7864bd18ea2901317bae8bbf06a5ade6dcf"}, - {file = "matplotlib-3.10.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3547d153d70233a8496859097ef0312212e2689cdf8d7ed764441c77604095ae"}, - {file = "matplotlib-3.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:c55b20591ced744aa04e8c3e4b7543ea4d650b6c3c4b208c08a05b4010e8b442"}, - {file = "matplotlib-3.10.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:9ade1003376731a971e398cc4ef38bb83ee8caf0aee46ac6daa4b0506db1fd06"}, - {file = "matplotlib-3.10.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:95b710fea129c76d30be72c3b38f330269363fbc6e570a5dd43580487380b5ff"}, - {file = "matplotlib-3.10.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cdbaf909887373c3e094b0318d7ff230b2ad9dcb64da7ade654182872ab2593"}, - {file = "matplotlib-3.10.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d907fddb39f923d011875452ff1eca29a9e7f21722b873e90db32e5d8ddff12e"}, - {file = "matplotlib-3.10.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:3b427392354d10975c1d0f4ee18aa5844640b512d5311ef32efd4dd7db106ede"}, - {file = "matplotlib-3.10.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5fd41b0ec7ee45cd960a8e71aea7c946a28a0b8a4dcee47d2856b2af051f334c"}, - {file = "matplotlib-3.10.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:81713dd0d103b379de4516b861d964b1d789a144103277769238c732229d7f03"}, - {file = "matplotlib-3.10.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:359f87baedb1f836ce307f0e850d12bb5f1936f70d035561f90d41d305fdacea"}, - {file = "matplotlib-3.10.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae80dc3a4add4665cf2faa90138384a7ffe2a4e37c58d83e115b54287c4f06ef"}, - {file = "matplotlib-3.10.0.tar.gz", hash = "sha256:b886d02a581b96704c9d1ffe55709e49b4d2d52709ccebc4be42db856e511278"}, + {file = "matplotlib-3.10.8-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:00270d217d6b20d14b584c521f810d60c5c78406dc289859776550df837dcda7"}, + {file = "matplotlib-3.10.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37b3c1cc42aa184b3f738cfa18c1c1d72fd496d85467a6cf7b807936d39aa656"}, + {file = "matplotlib-3.10.8-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ee40c27c795bda6a5292e9cff9890189d32f7e3a0bf04e0e3c9430c4a00c37df"}, + {file = "matplotlib-3.10.8-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a48f2b74020919552ea25d222d5cc6af9ca3f4eb43a93e14d068457f545c2a17"}, + {file = "matplotlib-3.10.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f254d118d14a7f99d616271d6c3c27922c092dac11112670b157798b89bf4933"}, + {file = "matplotlib-3.10.8-cp310-cp310-win_amd64.whl", hash = "sha256:f9b587c9c7274c1613a30afabf65a272114cd6cdbe67b3406f818c79d7ab2e2a"}, + {file = "matplotlib-3.10.8-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6be43b667360fef5c754dda5d25a32e6307a03c204f3c0fc5468b78fa87b4160"}, + {file = "matplotlib-3.10.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2b336e2d91a3d7006864e0990c83b216fcdca64b5a6484912902cef87313d78"}, + {file = "matplotlib-3.10.8-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:efb30e3baaea72ce5928e32bab719ab4770099079d66726a62b11b1ef7273be4"}, + {file = "matplotlib-3.10.8-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d56a1efd5bfd61486c8bc968fa18734464556f0fb8e51690f4ac25d85cbbbbc2"}, + {file = "matplotlib-3.10.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:238b7ce5717600615c895050239ec955d91f321c209dd110db988500558e70d6"}, + {file = "matplotlib-3.10.8-cp311-cp311-win_amd64.whl", hash = "sha256:18821ace09c763ec93aef5eeff087ee493a24051936d7b9ebcad9662f66501f9"}, + {file = "matplotlib-3.10.8-cp311-cp311-win_arm64.whl", hash = "sha256:bab485bcf8b1c7d2060b4fcb6fc368a9e6f4cd754c9c2fea281f4be21df394a2"}, + {file = "matplotlib-3.10.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:64fcc24778ca0404ce0cb7b6b77ae1f4c7231cdd60e6778f999ee05cbd581b9a"}, + {file = "matplotlib-3.10.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b9a5ca4ac220a0cdd1ba6bcba3608547117d30468fefce49bb26f55c1a3d5c58"}, + {file = "matplotlib-3.10.8-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3ab4aabc72de4ff77b3ec33a6d78a68227bf1123465887f9905ba79184a1cc04"}, + {file = "matplotlib-3.10.8-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:24d50994d8c5816ddc35411e50a86ab05f575e2530c02752e02538122613371f"}, + {file = "matplotlib-3.10.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:99eefd13c0dc3b3c1b4d561c1169e65fe47aab7b8158754d7c084088e2329466"}, + {file = "matplotlib-3.10.8-cp312-cp312-win_amd64.whl", hash = "sha256:dd80ecb295460a5d9d260df63c43f4afbdd832d725a531f008dad1664f458adf"}, + {file = "matplotlib-3.10.8-cp312-cp312-win_arm64.whl", hash = "sha256:3c624e43ed56313651bc18a47f838b60d7b8032ed348911c54906b130b20071b"}, + {file = "matplotlib-3.10.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3f2e409836d7f5ac2f1c013110a4d50b9f7edc26328c108915f9075d7d7a91b6"}, + {file = "matplotlib-3.10.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:56271f3dac49a88d7fca5060f004d9d22b865f743a12a23b1e937a0be4818ee1"}, + {file = "matplotlib-3.10.8-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a0a7f52498f72f13d4a25ea70f35f4cb60642b466cbb0a9be951b5bc3f45a486"}, + {file = "matplotlib-3.10.8-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:646d95230efb9ca614a7a594d4fcacde0ac61d25e37dd51710b36477594963ce"}, + {file = "matplotlib-3.10.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f89c151aab2e2e23cb3fe0acad1e8b82841fd265379c4cecd0f3fcb34c15e0f6"}, + {file = "matplotlib-3.10.8-cp313-cp313-win_amd64.whl", hash = "sha256:e8ea3e2d4066083e264e75c829078f9e149fa119d27e19acd503de65e0b13149"}, + {file = "matplotlib-3.10.8-cp313-cp313-win_arm64.whl", hash = "sha256:c108a1d6fa78a50646029cb6d49808ff0fc1330fda87fa6f6250c6b5369b6645"}, + {file = "matplotlib-3.10.8-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:ad3d9833a64cf48cc4300f2b406c3d0f4f4724a91c0bd5640678a6ba7c102077"}, + {file = "matplotlib-3.10.8-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:eb3823f11823deade26ce3b9f40dcb4a213da7a670013929f31d5f5ed1055b22"}, + {file = "matplotlib-3.10.8-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d9050fee89a89ed57b4fb2c1bfac9a3d0c57a0d55aed95949eedbc42070fea39"}, + {file = "matplotlib-3.10.8-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b44d07310e404ba95f8c25aa5536f154c0a8ec473303535949e52eb71d0a1565"}, + {file = "matplotlib-3.10.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:0a33deb84c15ede243aead39f77e990469fff93ad1521163305095b77b72ce4a"}, + {file = "matplotlib-3.10.8-cp313-cp313t-win_amd64.whl", hash = "sha256:3a48a78d2786784cc2413e57397981fb45c79e968d99656706018d6e62e57958"}, + {file = "matplotlib-3.10.8-cp313-cp313t-win_arm64.whl", hash = "sha256:15d30132718972c2c074cd14638c7f4592bd98719e2308bccea40e0538bc0cb5"}, + {file = "matplotlib-3.10.8-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b53285e65d4fa4c86399979e956235deb900be5baa7fc1218ea67fbfaeaadd6f"}, + {file = "matplotlib-3.10.8-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:32f8dce744be5569bebe789e46727946041199030db8aeb2954d26013a0eb26b"}, + {file = "matplotlib-3.10.8-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4cf267add95b1c88300d96ca837833d4112756045364f5c734a2276038dae27d"}, + {file = "matplotlib-3.10.8-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2cf5bd12cecf46908f286d7838b2abc6c91cda506c0445b8223a7c19a00df008"}, + {file = "matplotlib-3.10.8-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:41703cc95688f2516b480f7f339d8851a6035f18e100ee6a32bc0b8536a12a9c"}, + {file = "matplotlib-3.10.8-cp314-cp314-win_amd64.whl", hash = "sha256:83d282364ea9f3e52363da262ce32a09dfe241e4080dcedda3c0db059d3c1f11"}, + {file = "matplotlib-3.10.8-cp314-cp314-win_arm64.whl", hash = "sha256:2c1998e92cd5999e295a731bcb2911c75f597d937341f3030cc24ef2733d78a8"}, + {file = "matplotlib-3.10.8-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:b5a2b97dbdc7d4f353ebf343744f1d1f1cca8aa8bfddb4262fcf4306c3761d50"}, + {file = "matplotlib-3.10.8-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3f5c3e4da343bba819f0234186b9004faba952cc420fbc522dc4e103c1985908"}, + {file = "matplotlib-3.10.8-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f62550b9a30afde8c1c3ae450e5eb547d579dd69b25c2fc7a1c67f934c1717a"}, + {file = "matplotlib-3.10.8-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:495672de149445ec1b772ff2c9ede9b769e3cb4f0d0aa7fa730d7f59e2d4e1c1"}, + {file = "matplotlib-3.10.8-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:595ba4d8fe983b88f0eec8c26a241e16d6376fe1979086232f481f8f3f67494c"}, + {file = "matplotlib-3.10.8-cp314-cp314t-win_amd64.whl", hash = "sha256:25d380fe8b1dc32cf8f0b1b448470a77afb195438bafdf1d858bfb876f3edf7b"}, + {file = "matplotlib-3.10.8-cp314-cp314t-win_arm64.whl", hash = "sha256:113bb52413ea508ce954a02c10ffd0d565f9c3bc7f2eddc27dfe1731e71c7b5f"}, + {file = "matplotlib-3.10.8-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f97aeb209c3d2511443f8797e3e5a569aebb040d4f8bc79aa3ee78a8fb9e3dd8"}, + {file = "matplotlib-3.10.8-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fb061f596dad3a0f52b60dc6a5dec4a0c300dec41e058a7efe09256188d170b7"}, + {file = "matplotlib-3.10.8-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:12d90df9183093fcd479f4172ac26b322b1248b15729cb57f42f71f24c7e37a3"}, + {file = "matplotlib-3.10.8-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:6da7c2ce169267d0d066adcf63758f0604aa6c3eebf67458930f9d9b79ad1db1"}, + {file = "matplotlib-3.10.8-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9153c3292705be9f9c64498a8872118540c3f4123d1a1c840172edf262c8be4a"}, + {file = "matplotlib-3.10.8-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1ae029229a57cd1e8fe542485f27e7ca7b23aa9e8944ddb4985d0bc444f1eca2"}, + {file = "matplotlib-3.10.8.tar.gz", hash = "sha256:2299372c19d56bcd35cf05a2738308758d32b9eaed2371898d8f5bd33f084aa3"}, ] [package.dependencies] @@ -1074,7 +1296,7 @@ kiwisolver = ">=1.3.1" numpy = ">=1.23" packaging = ">=20.0" pillow = ">=8" -pyparsing = ">=2.3.1" +pyparsing = ">=3" python-dateutil = ">=2.7" [package.extras] @@ -1092,6 +1314,66 @@ files = [ {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, ] +[[package]] +name = "msal" +version = "1.35.0" +description = "The Microsoft Authentication Library (MSAL) for Python library enables your app to access the Microsoft Cloud by supporting authentication of users with Microsoft Azure Active Directory accounts (AAD) and Microsoft Accounts (MSA) using industry standard OAuth2 and OpenID Connect." +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "msal-1.35.0-py3-none-any.whl", hash = "sha256:baf268172d2b736e5d409689424d2f321b4142cab231b4b96594c86762e7e01d"}, + {file = "msal-1.35.0.tar.gz", hash = "sha256:76ab7513dbdac88d76abdc6a50110f082b7ed3ff1080aca938c53fc88bc75b51"}, +] + +[package.dependencies] +cryptography = ">=2.5,<49" +PyJWT = {version = ">=1.0.0,<3", extras = ["crypto"]} +requests = ">=2.0.0,<3" + +[package.extras] +broker = ["pymsalruntime (>=0.14,<0.21) ; python_version >= \"3.8\" and platform_system == \"Windows\"", "pymsalruntime (>=0.17,<0.21) ; python_version >= \"3.8\" and platform_system == \"Darwin\"", "pymsalruntime (>=0.18,<0.21) ; python_version >= \"3.8\" and platform_system == \"Linux\""] + +[[package]] +name = "msal-extensions" +version = "1.3.1" +description = "Microsoft Authentication Library extensions (MSAL EX) provides a persistence API that can save your data on disk, encrypted on Windows, macOS and Linux. Concurrent data access will be coordinated by a file lock mechanism." +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "msal_extensions-1.3.1-py3-none-any.whl", hash = "sha256:96d3de4d034504e969ac5e85bae8106c8373b5c6568e4c8fa7af2eca9dbe6bca"}, + {file = "msal_extensions-1.3.1.tar.gz", hash = "sha256:c5b0fd10f65ef62b5f1d62f4251d51cbcaf003fcedae8c91b040a488614be1a4"}, +] + +[package.dependencies] +msal = ">=1.29,<2" + +[package.extras] +portalocker = ["portalocker (>=1.4,<4)"] + +[[package]] +name = "msrest" +version = "0.7.1" +description = "AutoRest swagger generator Python client runtime." +optional = false +python-versions = ">=3.6" +groups = ["main"] +files = [ + {file = "msrest-0.7.1-py3-none-any.whl", hash = "sha256:21120a810e1233e5e6cc7fe40b474eeb4ec6f757a15d7cf86702c369f9567c32"}, + {file = "msrest-0.7.1.zip", hash = "sha256:6e7661f46f3afd88b75667b7187a92829924446c7ea1d169be8c4bb7eeb788b9"}, +] + +[package.dependencies] +azure-core = ">=1.24.0" +certifi = ">=2017.4.17" +isodate = ">=0.6.0" +requests = ">=2.16,<3.0" +requests-oauthlib = ">=0.5.0" + +[package.extras] +async = ["aiodns ; python_version >= \"3.5\"", "aiohttp (>=3.0) ; python_version >= \"3.5\""] + [[package]] name = "mypy-extensions" version = "1.0.0" @@ -1106,69 +1388,103 @@ files = [ [[package]] name = "numpy" -version = "2.2.3" +version = "2.4.2" description = "Fundamental package for array computing in Python" optional = false -python-versions = ">=3.10" +python-versions = ">=3.11" groups = ["main"] files = [ - {file = "numpy-2.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cbc6472e01952d3d1b2772b720428f8b90e2deea8344e854df22b0618e9cce71"}, - {file = "numpy-2.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cdfe0c22692a30cd830c0755746473ae66c4a8f2e7bd508b35fb3b6a0813d787"}, - {file = "numpy-2.2.3-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:e37242f5324ffd9f7ba5acf96d774f9276aa62a966c0bad8dae692deebec7716"}, - {file = "numpy-2.2.3-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:95172a21038c9b423e68be78fd0be6e1b97674cde269b76fe269a5dfa6fadf0b"}, - {file = "numpy-2.2.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5b47c440210c5d1d67e1cf434124e0b5c395eee1f5806fdd89b553ed1acd0a3"}, - {file = "numpy-2.2.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0391ea3622f5c51a2e29708877d56e3d276827ac5447d7f45e9bc4ade8923c52"}, - {file = "numpy-2.2.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f6b3dfc7661f8842babd8ea07e9897fe3d9b69a1d7e5fbb743e4160f9387833b"}, - {file = "numpy-2.2.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1ad78ce7f18ce4e7df1b2ea4019b5817a2f6a8a16e34ff2775f646adce0a5027"}, - {file = "numpy-2.2.3-cp310-cp310-win32.whl", hash = "sha256:5ebeb7ef54a7be11044c33a17b2624abe4307a75893c001a4800857956b41094"}, - {file = "numpy-2.2.3-cp310-cp310-win_amd64.whl", hash = "sha256:596140185c7fa113563c67c2e894eabe0daea18cf8e33851738c19f70ce86aeb"}, - {file = "numpy-2.2.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:16372619ee728ed67a2a606a614f56d3eabc5b86f8b615c79d01957062826ca8"}, - {file = "numpy-2.2.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5521a06a3148686d9269c53b09f7d399a5725c47bbb5b35747e1cb76326b714b"}, - {file = "numpy-2.2.3-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:7c8dde0ca2f77828815fd1aedfdf52e59071a5bae30dac3b4da2a335c672149a"}, - {file = "numpy-2.2.3-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:77974aba6c1bc26e3c205c2214f0d5b4305bdc719268b93e768ddb17e3fdd636"}, - {file = "numpy-2.2.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d42f9c36d06440e34226e8bd65ff065ca0963aeecada587b937011efa02cdc9d"}, - {file = "numpy-2.2.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2712c5179f40af9ddc8f6727f2bd910ea0eb50206daea75f58ddd9fa3f715bb"}, - {file = "numpy-2.2.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c8b0451d2ec95010d1db8ca733afc41f659f425b7f608af569711097fd6014e2"}, - {file = "numpy-2.2.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d9b4a8148c57ecac25a16b0e11798cbe88edf5237b0df99973687dd866f05e1b"}, - {file = "numpy-2.2.3-cp311-cp311-win32.whl", hash = "sha256:1f45315b2dc58d8a3e7754fe4e38b6fce132dab284a92851e41b2b344f6441c5"}, - {file = "numpy-2.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f48ba6f6c13e5e49f3d3efb1b51c8193215c42ac82610a04624906a9270be6f"}, - {file = "numpy-2.2.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:12c045f43b1d2915eca6b880a7f4a256f59d62df4f044788c8ba67709412128d"}, - {file = "numpy-2.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:87eed225fd415bbae787f93a457af7f5990b92a334e346f72070bf569b9c9c95"}, - {file = "numpy-2.2.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:712a64103d97c404e87d4d7c47fb0c7ff9acccc625ca2002848e0d53288b90ea"}, - {file = "numpy-2.2.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:a5ae282abe60a2db0fd407072aff4599c279bcd6e9a2475500fc35b00a57c532"}, - {file = "numpy-2.2.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5266de33d4c3420973cf9ae3b98b54a2a6d53a559310e3236c4b2b06b9c07d4e"}, - {file = "numpy-2.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b787adbf04b0db1967798dba8da1af07e387908ed1553a0d6e74c084d1ceafe"}, - {file = "numpy-2.2.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:34c1b7e83f94f3b564b35f480f5652a47007dd91f7c839f404d03279cc8dd021"}, - {file = "numpy-2.2.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4d8335b5f1b6e2bce120d55fb17064b0262ff29b459e8493d1785c18ae2553b8"}, - {file = "numpy-2.2.3-cp312-cp312-win32.whl", hash = "sha256:4d9828d25fb246bedd31e04c9e75714a4087211ac348cb39c8c5f99dbb6683fe"}, - {file = "numpy-2.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:83807d445817326b4bcdaaaf8e8e9f1753da04341eceec705c001ff342002e5d"}, - {file = "numpy-2.2.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7bfdb06b395385ea9b91bf55c1adf1b297c9fdb531552845ff1d3ea6e40d5aba"}, - {file = "numpy-2.2.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:23c9f4edbf4c065fddb10a4f6e8b6a244342d95966a48820c614891e5059bb50"}, - {file = "numpy-2.2.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:a0c03b6be48aaf92525cccf393265e02773be8fd9551a2f9adbe7db1fa2b60f1"}, - {file = "numpy-2.2.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:2376e317111daa0a6739e50f7ee2a6353f768489102308b0d98fcf4a04f7f3b5"}, - {file = "numpy-2.2.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8fb62fe3d206d72fe1cfe31c4a1106ad2b136fcc1606093aeab314f02930fdf2"}, - {file = "numpy-2.2.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52659ad2534427dffcc36aac76bebdd02b67e3b7a619ac67543bc9bfe6b7cdb1"}, - {file = "numpy-2.2.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1b416af7d0ed3271cad0f0a0d0bee0911ed7eba23e66f8424d9f3dfcdcae1304"}, - {file = "numpy-2.2.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1402da8e0f435991983d0a9708b779f95a8c98c6b18a171b9f1be09005e64d9d"}, - {file = "numpy-2.2.3-cp313-cp313-win32.whl", hash = "sha256:136553f123ee2951bfcfbc264acd34a2fc2f29d7cdf610ce7daf672b6fbaa693"}, - {file = "numpy-2.2.3-cp313-cp313-win_amd64.whl", hash = "sha256:5b732c8beef1d7bc2d9e476dbba20aaff6167bf205ad9aa8d30913859e82884b"}, - {file = "numpy-2.2.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:435e7a933b9fda8126130b046975a968cc2d833b505475e588339e09f7672890"}, - {file = "numpy-2.2.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:7678556eeb0152cbd1522b684dcd215250885993dd00adb93679ec3c0e6e091c"}, - {file = "numpy-2.2.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:2e8da03bd561504d9b20e7a12340870dfc206c64ea59b4cfee9fceb95070ee94"}, - {file = "numpy-2.2.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:c9aa4496fd0e17e3843399f533d62857cef5900facf93e735ef65aa4bbc90ef0"}, - {file = "numpy-2.2.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4ca91d61a4bf61b0f2228f24bbfa6a9facd5f8af03759fe2a655c50ae2c6610"}, - {file = "numpy-2.2.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:deaa09cd492e24fd9b15296844c0ad1b3c976da7907e1c1ed3a0ad21dded6f76"}, - {file = "numpy-2.2.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:246535e2f7496b7ac85deffe932896a3577be7af8fb7eebe7146444680297e9a"}, - {file = "numpy-2.2.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:daf43a3d1ea699402c5a850e5313680ac355b4adc9770cd5cfc2940e7861f1bf"}, - {file = "numpy-2.2.3-cp313-cp313t-win32.whl", hash = "sha256:cf802eef1f0134afb81fef94020351be4fe1d6681aadf9c5e862af6602af64ef"}, - {file = "numpy-2.2.3-cp313-cp313t-win_amd64.whl", hash = "sha256:aee2512827ceb6d7f517c8b85aa5d3923afe8fc7a57d028cffcd522f1c6fd082"}, - {file = "numpy-2.2.3-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3c2ec8a0f51d60f1e9c0c5ab116b7fc104b165ada3f6c58abf881cb2eb16044d"}, - {file = "numpy-2.2.3-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:ed2cf9ed4e8ebc3b754d398cba12f24359f018b416c380f577bbae112ca52fc9"}, - {file = "numpy-2.2.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39261798d208c3095ae4f7bc8eaeb3481ea8c6e03dc48028057d3cbdbdb8937e"}, - {file = "numpy-2.2.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:783145835458e60fa97afac25d511d00a1eca94d4a8f3ace9fe2043003c678e4"}, - {file = "numpy-2.2.3.tar.gz", hash = "sha256:dbdc15f0c81611925f382dfa97b3bd0bc2c1ce19d4fe50482cb0ddc12ba30020"}, + {file = "numpy-2.4.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e7e88598032542bd49af7c4747541422884219056c268823ef6e5e89851c8825"}, + {file = "numpy-2.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7edc794af8b36ca37ef5fcb5e0d128c7e0595c7b96a2318d1badb6fcd8ee86b1"}, + {file = "numpy-2.4.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:6e9f61981ace1360e42737e2bae58b27bf28a1b27e781721047d84bd754d32e7"}, + {file = "numpy-2.4.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:cb7bbb88aa74908950d979eeaa24dbdf1a865e3c7e45ff0121d8f70387b55f73"}, + {file = "numpy-2.4.2-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4f069069931240b3fc703f1e23df63443dbd6390614c8c44a87d96cd0ec81eb1"}, + {file = "numpy-2.4.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c02ef4401a506fb60b411467ad501e1429a3487abca4664871d9ae0b46c8ba32"}, + {file = "numpy-2.4.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2653de5c24910e49c2b106499803124dde62a5a1fe0eedeaecf4309a5f639390"}, + {file = "numpy-2.4.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1ae241bbfc6ae276f94a170b14785e561cb5e7f626b6688cf076af4110887413"}, + {file = "numpy-2.4.2-cp311-cp311-win32.whl", hash = "sha256:df1b10187212b198dd45fa943d8985a3c8cf854aed4923796e0e019e113a1bda"}, + {file = "numpy-2.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:b9c618d56a29c9cb1c4da979e9899be7578d2e0b3c24d52079c166324c9e8695"}, + {file = "numpy-2.4.2-cp311-cp311-win_arm64.whl", hash = "sha256:47c5a6ed21d9452b10227e5e8a0e1c22979811cad7dcc19d8e3e2fb8fa03f1a3"}, + {file = "numpy-2.4.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:21982668592194c609de53ba4933a7471880ccbaadcc52352694a59ecc860b3a"}, + {file = "numpy-2.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40397bda92382fcec844066efb11f13e1c9a3e2a8e8f318fb72ed8b6db9f60f1"}, + {file = "numpy-2.4.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:b3a24467af63c67829bfaa61eecf18d5432d4f11992688537be59ecd6ad32f5e"}, + {file = "numpy-2.4.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:805cc8de9fd6e7a22da5aed858e0ab16be5a4db6c873dde1d7451c541553aa27"}, + {file = "numpy-2.4.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d82351358ffbcdcd7b686b90742a9b86632d6c1c051016484fa0b326a0a1548"}, + {file = "numpy-2.4.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e35d3e0144137d9fdae62912e869136164534d64a169f86438bc9561b6ad49f"}, + {file = "numpy-2.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:adb6ed2ad29b9e15321d167d152ee909ec73395901b70936f029c3bc6d7f4460"}, + {file = "numpy-2.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8906e71fd8afcb76580404e2a950caef2685df3d2a57fe82a86ac8d33cc007ba"}, + {file = "numpy-2.4.2-cp312-cp312-win32.whl", hash = "sha256:ec055f6dae239a6299cace477b479cca2fc125c5675482daf1dd886933a1076f"}, + {file = "numpy-2.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:209fae046e62d0ce6435fcfe3b1a10537e858249b3d9b05829e2a05218296a85"}, + {file = "numpy-2.4.2-cp312-cp312-win_arm64.whl", hash = "sha256:fbde1b0c6e81d56f5dccd95dd4a711d9b95df1ae4009a60887e56b27e8d903fa"}, + {file = "numpy-2.4.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:25f2059807faea4b077a2b6837391b5d830864b3543627f381821c646f31a63c"}, + {file = "numpy-2.4.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bd3a7a9f5847d2fb8c2c6d1c862fa109c31a9abeca1a3c2bd5a64572955b2979"}, + {file = "numpy-2.4.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:8e4549f8a3c6d13d55041925e912bfd834285ef1dd64d6bc7d542583355e2e98"}, + {file = "numpy-2.4.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:aea4f66ff44dfddf8c2cffd66ba6538c5ec67d389285292fe428cb2c738c8aef"}, + {file = "numpy-2.4.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c3cd545784805de05aafe1dde61752ea49a359ccba9760c1e5d1c88a93bbf2b7"}, + {file = "numpy-2.4.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0d9b7c93578baafcbc5f0b83eaf17b79d345c6f36917ba0c67f45226911d499"}, + {file = "numpy-2.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f74f0f7779cc7ae07d1810aab8ac6b1464c3eafb9e283a40da7309d5e6e48fbb"}, + {file = "numpy-2.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c7ac672d699bf36275c035e16b65539931347d68b70667d28984c9fb34e07fa7"}, + {file = "numpy-2.4.2-cp313-cp313-win32.whl", hash = "sha256:8e9afaeb0beff068b4d9cd20d322ba0ee1cecfb0b08db145e4ab4dd44a6b5110"}, + {file = "numpy-2.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:7df2de1e4fba69a51c06c28f5a3de36731eb9639feb8e1cf7e4a7b0daf4cf622"}, + {file = "numpy-2.4.2-cp313-cp313-win_arm64.whl", hash = "sha256:0fece1d1f0a89c16b03442eae5c56dc0be0c7883b5d388e0c03f53019a4bfd71"}, + {file = "numpy-2.4.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5633c0da313330fd20c484c78cdd3f9b175b55e1a766c4a174230c6b70ad8262"}, + {file = "numpy-2.4.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d9f64d786b3b1dd742c946c42d15b07497ed14af1a1f3ce840cce27daa0ce913"}, + {file = "numpy-2.4.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:b21041e8cb6a1eb5312dd1d2f80a94d91efffb7a06b70597d44f1bd2dfc315ab"}, + {file = "numpy-2.4.2-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:00ab83c56211a1d7c07c25e3217ea6695e50a3e2f255053686b081dc0b091a82"}, + {file = "numpy-2.4.2-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2fb882da679409066b4603579619341c6d6898fc83a8995199d5249f986e8e8f"}, + {file = "numpy-2.4.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:66cb9422236317f9d44b67b4d18f44efe6e9c7f8794ac0462978513359461554"}, + {file = "numpy-2.4.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:0f01dcf33e73d80bd8dc0f20a71303abbafa26a19e23f6b68d1aa9990af90257"}, + {file = "numpy-2.4.2-cp313-cp313t-win32.whl", hash = "sha256:52b913ec40ff7ae845687b0b34d8d93b60cb66dcee06996dd5c99f2fc9328657"}, + {file = "numpy-2.4.2-cp313-cp313t-win_amd64.whl", hash = "sha256:5eea80d908b2c1f91486eb95b3fb6fab187e569ec9752ab7d9333d2e66bf2d6b"}, + {file = "numpy-2.4.2-cp313-cp313t-win_arm64.whl", hash = "sha256:fd49860271d52127d61197bb50b64f58454e9f578cb4b2c001a6de8b1f50b0b1"}, + {file = "numpy-2.4.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:444be170853f1f9d528428eceb55f12918e4fda5d8805480f36a002f1415e09b"}, + {file = "numpy-2.4.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d1240d50adff70c2a88217698ca844723068533f3f5c5fa6ee2e3220e3bdb000"}, + {file = "numpy-2.4.2-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:7cdde6de52fb6664b00b056341265441192d1291c130e99183ec0d4b110ff8b1"}, + {file = "numpy-2.4.2-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:cda077c2e5b780200b6b3e09d0b42205a3d1c68f30c6dceb90401c13bff8fe74"}, + {file = "numpy-2.4.2-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d30291931c915b2ab5717c2974bb95ee891a1cf22ebc16a8006bd59cd210d40a"}, + {file = "numpy-2.4.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bba37bc29d4d85761deed3954a1bc62be7cf462b9510b51d367b769a8c8df325"}, + {file = "numpy-2.4.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b2f0073ed0868db1dcd86e052d37279eef185b9c8db5bf61f30f46adac63c909"}, + {file = "numpy-2.4.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7f54844851cdb630ceb623dcec4db3240d1ac13d4990532446761baede94996a"}, + {file = "numpy-2.4.2-cp314-cp314-win32.whl", hash = "sha256:12e26134a0331d8dbd9351620f037ec470b7c75929cb8a1537f6bfe411152a1a"}, + {file = "numpy-2.4.2-cp314-cp314-win_amd64.whl", hash = "sha256:068cdb2d0d644cdb45670810894f6a0600797a69c05f1ac478e8d31670b8ee75"}, + {file = "numpy-2.4.2-cp314-cp314-win_arm64.whl", hash = "sha256:6ed0be1ee58eef41231a5c943d7d1375f093142702d5723ca2eb07db9b934b05"}, + {file = "numpy-2.4.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:98f16a80e917003a12c0580f97b5f875853ebc33e2eaa4bccfc8201ac6869308"}, + {file = "numpy-2.4.2-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:20abd069b9cda45874498b245c8015b18ace6de8546bf50dfa8cea1696ed06ef"}, + {file = "numpy-2.4.2-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:e98c97502435b53741540a5717a6749ac2ada901056c7db951d33e11c885cc7d"}, + {file = "numpy-2.4.2-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:da6cad4e82cb893db4b69105c604d805e0c3ce11501a55b5e9f9083b47d2ffe8"}, + {file = "numpy-2.4.2-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e4424677ce4b47fe73c8b5556d876571f7c6945d264201180db2dc34f676ab5"}, + {file = "numpy-2.4.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2b8f157c8a6f20eb657e240f8985cc135598b2b46985c5bccbde7616dc9c6b1e"}, + {file = "numpy-2.4.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5daf6f3914a733336dab21a05cdec343144600e964d2fcdabaac0c0269874b2a"}, + {file = "numpy-2.4.2-cp314-cp314t-win32.whl", hash = "sha256:8c50dd1fc8826f5b26a5ee4d77ca55d88a895f4e4819c7ecc2a9f5905047a443"}, + {file = "numpy-2.4.2-cp314-cp314t-win_amd64.whl", hash = "sha256:fcf92bee92742edd401ba41135185866f7026c502617f422eb432cfeca4fe236"}, + {file = "numpy-2.4.2-cp314-cp314t-win_arm64.whl", hash = "sha256:1f92f53998a17265194018d1cc321b2e96e900ca52d54c7c77837b71b9465181"}, + {file = "numpy-2.4.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:89f7268c009bc492f506abd6f5265defa7cb3f7487dc21d357c3d290add45082"}, + {file = "numpy-2.4.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:e6dee3bb76aa4009d5a912180bf5b2de012532998d094acee25d9cb8dee3e44a"}, + {file = "numpy-2.4.2-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:cd2bd2bbed13e213d6b55dc1d035a4f91748a7d3edc9480c13898b0353708920"}, + {file = "numpy-2.4.2-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:cf28c0c1d4c4bf00f509fa7eb02c58d7caf221b50b467bcb0d9bbf1584d5c821"}, + {file = "numpy-2.4.2-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e04ae107ac591763a47398bb45b568fc38f02dbc4aa44c063f67a131f99346cb"}, + {file = "numpy-2.4.2-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:602f65afdef699cda27ec0b9224ae5dc43e328f4c24c689deaf77133dbee74d0"}, + {file = "numpy-2.4.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:be71bf1edb48ebbbf7f6337b5bfd2f895d1902f6335a5830b20141fc126ffba0"}, + {file = "numpy-2.4.2.tar.gz", hash = "sha256:659a6107e31a83c4e33f763942275fd278b21d095094044eb35569e86a21ddae"}, ] +[[package]] +name = "oauthlib" +version = "3.2.2" +description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" +optional = false +python-versions = ">=3.6" +groups = ["main"] +files = [ + {file = "oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca"}, + {file = "oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"}, +] + +[package.extras] +rsa = ["cryptography (>=3.0.0)"] +signals = ["blinker (>=1.4.0)"] +signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] + [[package]] name = "openpyxl" version = "3.1.5" @@ -1184,6 +1500,307 @@ files = [ [package.dependencies] et-xmlfile = "*" +[[package]] +name = "opentelemetry-api" +version = "1.39.0" +description = "OpenTelemetry Python API" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "opentelemetry_api-1.39.0-py3-none-any.whl", hash = "sha256:3c3b3ca5c5687b1b5b37e5c5027ff68eacea8675241b29f13110a8ffbb8f0459"}, + {file = "opentelemetry_api-1.39.0.tar.gz", hash = "sha256:6130644268c5ac6bdffaf660ce878f10906b3e789f7e2daa5e169b047a2933b9"}, +] + +[package.dependencies] +importlib-metadata = ">=6.0,<8.8.0" +typing-extensions = ">=4.5.0" + +[[package]] +name = "opentelemetry-instrumentation" +version = "0.60b0" +description = "Instrumentation Tools & Auto Instrumentation for OpenTelemetry Python" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "opentelemetry_instrumentation-0.60b0-py3-none-any.whl", hash = "sha256:aaafa1483543a402819f1bdfb06af721c87d60dd109501f9997332862a35c76a"}, + {file = "opentelemetry_instrumentation-0.60b0.tar.gz", hash = "sha256:4e9fec930f283a2677a2217754b40aaf9ef76edae40499c165bc7f1d15366a74"}, +] + +[package.dependencies] +opentelemetry-api = ">=1.4,<2.0" +opentelemetry-semantic-conventions = "0.60b0" +packaging = ">=18.0" +wrapt = ">=1.0.0,<2.0.0" + +[[package]] +name = "opentelemetry-instrumentation-asgi" +version = "0.60b0" +description = "ASGI instrumentation for OpenTelemetry" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "opentelemetry_instrumentation_asgi-0.60b0-py3-none-any.whl", hash = "sha256:9d76a541269452c718a0384478f3291feb650c5a3f29e578fdc6613ea3729cf3"}, + {file = "opentelemetry_instrumentation_asgi-0.60b0.tar.gz", hash = "sha256:928731218050089dca69f0fe980b8bfe109f384be8b89802d7337372ddb67b91"}, +] + +[package.dependencies] +asgiref = ">=3.0,<4.0" +opentelemetry-api = ">=1.12,<2.0" +opentelemetry-instrumentation = "0.60b0" +opentelemetry-semantic-conventions = "0.60b0" +opentelemetry-util-http = "0.60b0" + +[package.extras] +instruments = ["asgiref (>=3.0,<4.0)"] + +[[package]] +name = "opentelemetry-instrumentation-dbapi" +version = "0.60b0" +description = "OpenTelemetry Database API instrumentation" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "opentelemetry_instrumentation_dbapi-0.60b0-py3-none-any.whl", hash = "sha256:429d8ca34a44a4296b9b09a1bd373fff350998d200525c6e79883c3328559b03"}, + {file = "opentelemetry_instrumentation_dbapi-0.60b0.tar.gz", hash = "sha256:2b7eb38e46890cebe5bc1a1c03d2ab07fc159b0b7b91342941ee33dd73876d84"}, +] + +[package.dependencies] +opentelemetry-api = ">=1.12,<2.0" +opentelemetry-instrumentation = "0.60b0" +opentelemetry-semantic-conventions = "0.60b0" +wrapt = ">=1.0.0,<2.0.0" + +[[package]] +name = "opentelemetry-instrumentation-django" +version = "0.60b0" +description = "OpenTelemetry Instrumentation for Django" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "opentelemetry_instrumentation_django-0.60b0-py3-none-any.whl", hash = "sha256:95495649c8c34ce9217c6873cdd10fc4fcaa67c25f8329adc54f5b286999e40b"}, + {file = "opentelemetry_instrumentation_django-0.60b0.tar.gz", hash = "sha256:461e6fca27936ba97eec26da38bb5f19310783370478c7ca3a3e40faaceac9cc"}, +] + +[package.dependencies] +opentelemetry-api = ">=1.12,<2.0" +opentelemetry-instrumentation = "0.60b0" +opentelemetry-instrumentation-wsgi = "0.60b0" +opentelemetry-semantic-conventions = "0.60b0" +opentelemetry-util-http = "0.60b0" + +[package.extras] +asgi = ["opentelemetry-instrumentation-asgi (==0.60b0)"] +instruments = ["django (>=1.10)"] + +[[package]] +name = "opentelemetry-instrumentation-fastapi" +version = "0.60b0" +description = "OpenTelemetry FastAPI Instrumentation" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "opentelemetry_instrumentation_fastapi-0.60b0-py3-none-any.whl", hash = "sha256:415c6602db01ee339276ea4cabe3e80177c9e955631c087f2ef60a75e31bfaee"}, + {file = "opentelemetry_instrumentation_fastapi-0.60b0.tar.gz", hash = "sha256:5d34d67eb634a08bfe9e530680d6177521cd9da79285144e6d5a8f42683ed1b3"}, +] + +[package.dependencies] +opentelemetry-api = ">=1.12,<2.0" +opentelemetry-instrumentation = "0.60b0" +opentelemetry-instrumentation-asgi = "0.60b0" +opentelemetry-semantic-conventions = "0.60b0" +opentelemetry-util-http = "0.60b0" + +[package.extras] +instruments = ["fastapi (>=0.92,<1.0)"] + +[[package]] +name = "opentelemetry-instrumentation-flask" +version = "0.60b0" +description = "Flask instrumentation for OpenTelemetry" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "opentelemetry_instrumentation_flask-0.60b0-py3-none-any.whl", hash = "sha256:106e5774f79ac9b86dd0d949c1b8f46c807a8af16184301e10d24fc94e680d04"}, + {file = "opentelemetry_instrumentation_flask-0.60b0.tar.gz", hash = "sha256:560f08598ef40cdcf7ca05bfb2e3ea74fab076e676f4c18bb36bb379bf5c4a1b"}, +] + +[package.dependencies] +opentelemetry-api = ">=1.12,<2.0" +opentelemetry-instrumentation = "0.60b0" +opentelemetry-instrumentation-wsgi = "0.60b0" +opentelemetry-semantic-conventions = "0.60b0" +opentelemetry-util-http = "0.60b0" +packaging = ">=21.0" + +[package.extras] +instruments = ["flask (>=1.0)"] + +[[package]] +name = "opentelemetry-instrumentation-psycopg2" +version = "0.60b0" +description = "OpenTelemetry psycopg2 instrumentation" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "opentelemetry_instrumentation_psycopg2-0.60b0-py3-none-any.whl", hash = "sha256:ea136a32babd559aa717c04dddf6aa78aa94b816fb4e10dfe06751727ef306d4"}, + {file = "opentelemetry_instrumentation_psycopg2-0.60b0.tar.gz", hash = "sha256:59e527fd97739440380634ffcf9431aa7f2965d939d8d5829790886e2b54ede9"}, +] + +[package.dependencies] +opentelemetry-api = ">=1.12,<2.0" +opentelemetry-instrumentation = "0.60b0" +opentelemetry-instrumentation-dbapi = "0.60b0" + +[package.extras] +instruments-any = ["psycopg2 (>=2.7.3.1)", "psycopg2-binary (>=2.7.3.1)"] + +[[package]] +name = "opentelemetry-instrumentation-requests" +version = "0.60b0" +description = "OpenTelemetry requests instrumentation" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "opentelemetry_instrumentation_requests-0.60b0-py3-none-any.whl", hash = "sha256:e9957f3a650ae55502fa227b29ff985b37d63e41c85e6e1555d48039f092ea83"}, + {file = "opentelemetry_instrumentation_requests-0.60b0.tar.gz", hash = "sha256:5079ed8df96d01dab915a0766cd28a49be7c33439ce43d6d39843ed6dee3204f"}, +] + +[package.dependencies] +opentelemetry-api = ">=1.12,<2.0" +opentelemetry-instrumentation = "0.60b0" +opentelemetry-semantic-conventions = "0.60b0" +opentelemetry-util-http = "0.60b0" + +[package.extras] +instruments = ["requests (>=2.0,<3.0)"] + +[[package]] +name = "opentelemetry-instrumentation-urllib" +version = "0.60b0" +description = "OpenTelemetry urllib instrumentation" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "opentelemetry_instrumentation_urllib-0.60b0-py3-none-any.whl", hash = "sha256:80e3545d02505dc0ea61b3a0a141ec2828e11bee6b7dedfd3ee7ed9a7adbf862"}, + {file = "opentelemetry_instrumentation_urllib-0.60b0.tar.gz", hash = "sha256:89b8796f9ab64d0ea0833cfea98745963baa0d7e4a775b3d2a77791aa97cf3f9"}, +] + +[package.dependencies] +opentelemetry-api = ">=1.12,<2.0" +opentelemetry-instrumentation = "0.60b0" +opentelemetry-semantic-conventions = "0.60b0" +opentelemetry-util-http = "0.60b0" + +[[package]] +name = "opentelemetry-instrumentation-urllib3" +version = "0.60b0" +description = "OpenTelemetry urllib3 instrumentation" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "opentelemetry_instrumentation_urllib3-0.60b0-py3-none-any.whl", hash = "sha256:9a07504560feae650a9205b3e2a579a835819bb1d55498d26a5db477fe04bba0"}, + {file = "opentelemetry_instrumentation_urllib3-0.60b0.tar.gz", hash = "sha256:6ae1640a993901bae8eda5496d8b1440fb326a29e4ba1db342738b8868174aad"}, +] + +[package.dependencies] +opentelemetry-api = ">=1.12,<2.0" +opentelemetry-instrumentation = "0.60b0" +opentelemetry-semantic-conventions = "0.60b0" +opentelemetry-util-http = "0.60b0" +wrapt = ">=1.0.0,<2.0.0" + +[package.extras] +instruments = ["urllib3 (>=1.0.0,<3.0.0)"] + +[[package]] +name = "opentelemetry-instrumentation-wsgi" +version = "0.60b0" +description = "WSGI Middleware for OpenTelemetry" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "opentelemetry_instrumentation_wsgi-0.60b0-py3-none-any.whl", hash = "sha256:0ff80614c1e73f7e94a5860c7e6222a51195eebab3dc5f50d89013db3d5d2f13"}, + {file = "opentelemetry_instrumentation_wsgi-0.60b0.tar.gz", hash = "sha256:5815195b1b9890f55c4baafec94ff98591579a7d9b16256064adea8ee5784651"}, +] + +[package.dependencies] +opentelemetry-api = ">=1.12,<2.0" +opentelemetry-instrumentation = "0.60b0" +opentelemetry-semantic-conventions = "0.60b0" +opentelemetry-util-http = "0.60b0" + +[[package]] +name = "opentelemetry-resource-detector-azure" +version = "0.1.5" +description = "Azure Resource Detector for OpenTelemetry" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "opentelemetry_resource_detector_azure-0.1.5-py3-none-any.whl", hash = "sha256:4dcc5d54ab5c3b11226af39509bc98979a8b9e0f8a24c1b888783755d3bf00eb"}, + {file = "opentelemetry_resource_detector_azure-0.1.5.tar.gz", hash = "sha256:e0ba658a87c69eebc806e75398cd0e9f68a8898ea62de99bc1b7083136403710"}, +] + +[package.dependencies] +opentelemetry-sdk = ">=1.21,<2.0" + +[[package]] +name = "opentelemetry-sdk" +version = "1.39.0" +description = "OpenTelemetry Python SDK" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "opentelemetry_sdk-1.39.0-py3-none-any.whl", hash = "sha256:90cfb07600dfc0d2de26120cebc0c8f27e69bf77cd80ef96645232372709a514"}, + {file = "opentelemetry_sdk-1.39.0.tar.gz", hash = "sha256:c22204f12a0529e07aa4d985f1bca9d6b0e7b29fe7f03e923548ae52e0e15dde"}, +] + +[package.dependencies] +opentelemetry-api = "1.39.0" +opentelemetry-semantic-conventions = "0.60b0" +typing-extensions = ">=4.5.0" + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.60b0" +description = "OpenTelemetry Semantic Conventions" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "opentelemetry_semantic_conventions-0.60b0-py3-none-any.whl", hash = "sha256:069530852691136018087b52688857d97bba61cd641d0f8628d2d92788c4f78a"}, + {file = "opentelemetry_semantic_conventions-0.60b0.tar.gz", hash = "sha256:227d7aa73cbb8a2e418029d6b6465553aa01cf7e78ec9d0bc3255c7b3ac5bf8f"}, +] + +[package.dependencies] +opentelemetry-api = "1.39.0" +typing-extensions = ">=4.5.0" + +[[package]] +name = "opentelemetry-util-http" +version = "0.60b0" +description = "Web util for OpenTelemetry" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "opentelemetry_util_http-0.60b0-py3-none-any.whl", hash = "sha256:4f366f1a48adb74ffa6f80aee26f96882e767e01b03cd1cfb948b6e1020341fe"}, + {file = "opentelemetry_util_http-0.60b0.tar.gz", hash = "sha256:e42b7bb49bba43b6f34390327d97e5016eb1c47949ceaf37c4795472a4e3a82d"}, +] + [[package]] name = "packaging" version = "24.2" @@ -1198,99 +1815,114 @@ files = [ [[package]] name = "pandas" -version = "2.2.3" +version = "3.0.1" description = "Powerful data structures for data analysis, time series, and statistics" optional = false -python-versions = ">=3.9" +python-versions = ">=3.11" groups = ["main"] files = [ - {file = "pandas-2.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1948ddde24197a0f7add2bdc4ca83bf2b1ef84a1bc8ccffd95eda17fd836ecb5"}, - {file = "pandas-2.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:381175499d3802cde0eabbaf6324cce0c4f5d52ca6f8c377c29ad442f50f6348"}, - {file = "pandas-2.2.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d9c45366def9a3dd85a6454c0e7908f2b3b8e9c138f5dc38fed7ce720d8453ed"}, - {file = "pandas-2.2.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86976a1c5b25ae3f8ccae3a5306e443569ee3c3faf444dfd0f41cda24667ad57"}, - {file = "pandas-2.2.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b8661b0238a69d7aafe156b7fa86c44b881387509653fdf857bebc5e4008ad42"}, - {file = "pandas-2.2.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:37e0aced3e8f539eccf2e099f65cdb9c8aa85109b0be6e93e2baff94264bdc6f"}, - {file = "pandas-2.2.3-cp310-cp310-win_amd64.whl", hash = "sha256:56534ce0746a58afaf7942ba4863e0ef81c9c50d3f0ae93e9497d6a41a057645"}, - {file = "pandas-2.2.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:66108071e1b935240e74525006034333f98bcdb87ea116de573a6a0dccb6c039"}, - {file = "pandas-2.2.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7c2875855b0ff77b2a64a0365e24455d9990730d6431b9e0ee18ad8acee13dbd"}, - {file = "pandas-2.2.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cd8d0c3be0515c12fed0bdbae072551c8b54b7192c7b1fda0ba56059a0179698"}, - {file = "pandas-2.2.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c124333816c3a9b03fbeef3a9f230ba9a737e9e5bb4060aa2107a86cc0a497fc"}, - {file = "pandas-2.2.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:63cc132e40a2e084cf01adf0775b15ac515ba905d7dcca47e9a251819c575ef3"}, - {file = "pandas-2.2.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:29401dbfa9ad77319367d36940cd8a0b3a11aba16063e39632d98b0e931ddf32"}, - {file = "pandas-2.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:3fc6873a41186404dad67245896a6e440baacc92f5b716ccd1bc9ed2995ab2c5"}, - {file = "pandas-2.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b1d432e8d08679a40e2a6d8b2f9770a5c21793a6f9f47fdd52c5ce1948a5a8a9"}, - {file = "pandas-2.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a5a1595fe639f5988ba6a8e5bc9649af3baf26df3998a0abe56c02609392e0a4"}, - {file = "pandas-2.2.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5de54125a92bb4d1c051c0659e6fcb75256bf799a732a87184e5ea503965bce3"}, - {file = "pandas-2.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fffb8ae78d8af97f849404f21411c95062db1496aeb3e56f146f0355c9989319"}, - {file = "pandas-2.2.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dfcb5ee8d4d50c06a51c2fffa6cff6272098ad6540aed1a76d15fb9318194d8"}, - {file = "pandas-2.2.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:062309c1b9ea12a50e8ce661145c6aab431b1e99530d3cd60640e255778bd43a"}, - {file = "pandas-2.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:59ef3764d0fe818125a5097d2ae867ca3fa64df032331b7e0917cf5d7bf66b13"}, - {file = "pandas-2.2.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f00d1345d84d8c86a63e476bb4955e46458b304b9575dcf71102b5c705320015"}, - {file = "pandas-2.2.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3508d914817e153ad359d7e069d752cdd736a247c322d932eb89e6bc84217f28"}, - {file = "pandas-2.2.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22a9d949bfc9a502d320aa04e5d02feab689d61da4e7764b62c30b991c42c5f0"}, - {file = "pandas-2.2.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3a255b2c19987fbbe62a9dfd6cff7ff2aa9ccab3fc75218fd4b7530f01efa24"}, - {file = "pandas-2.2.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:800250ecdadb6d9c78eae4990da62743b857b470883fa27f652db8bdde7f6659"}, - {file = "pandas-2.2.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6374c452ff3ec675a8f46fd9ab25c4ad0ba590b71cf0656f8b6daa5202bca3fb"}, - {file = "pandas-2.2.3-cp313-cp313-win_amd64.whl", hash = "sha256:61c5ad4043f791b61dd4752191d9f07f0ae412515d59ba8f005832a532f8736d"}, - {file = "pandas-2.2.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3b71f27954685ee685317063bf13c7709a7ba74fc996b84fc6821c59b0f06468"}, - {file = "pandas-2.2.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:38cf8125c40dae9d5acc10fa66af8ea6fdf760b2714ee482ca691fc66e6fcb18"}, - {file = "pandas-2.2.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ba96630bc17c875161df3818780af30e43be9b166ce51c9a18c1feae342906c2"}, - {file = "pandas-2.2.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1db71525a1538b30142094edb9adc10be3f3e176748cd7acc2240c2f2e5aa3a4"}, - {file = "pandas-2.2.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:15c0e1e02e93116177d29ff83e8b1619c93ddc9c49083f237d4312337a61165d"}, - {file = "pandas-2.2.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ad5b65698ab28ed8d7f18790a0dc58005c7629f227be9ecc1072aa74c0c1d43a"}, - {file = "pandas-2.2.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc6b93f9b966093cb0fd62ff1a7e4c09e6d546ad7c1de191767baffc57628f39"}, - {file = "pandas-2.2.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5dbca4c1acd72e8eeef4753eeca07de9b1db4f398669d5994086f788a5d7cc30"}, - {file = "pandas-2.2.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8cd6d7cc958a3910f934ea8dbdf17b2364827bb4dafc38ce6eef6bb3d65ff09c"}, - {file = "pandas-2.2.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99df71520d25fade9db7c1076ac94eb994f4d2673ef2aa2e86ee039b6746d20c"}, - {file = "pandas-2.2.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:31d0ced62d4ea3e231a9f228366919a5ea0b07440d9d4dac345376fd8e1477ea"}, - {file = "pandas-2.2.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7eee9e7cea6adf3e3d24e304ac6b8300646e2a5d1cd3a3c2abed9101b0846761"}, - {file = "pandas-2.2.3-cp39-cp39-win_amd64.whl", hash = "sha256:4850ba03528b6dd51d6c5d273c46f183f39a9baf3f0143e566b89450965b105e"}, - {file = "pandas-2.2.3.tar.gz", hash = "sha256:4f18ba62b61d7e192368b84517265a99b4d7ee8912f8708660fb4a366cc82667"}, + {file = "pandas-3.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:de09668c1bf3b925c07e5762291602f0d789eca1b3a781f99c1c78f6cac0e7ea"}, + {file = "pandas-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:24ba315ba3d6e5806063ac6eb717504e499ce30bd8c236d8693a5fd3f084c796"}, + {file = "pandas-3.0.1-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:406ce835c55bac912f2a0dcfaf27c06d73c6b04a5dde45f1fd3169ce31337389"}, + {file = "pandas-3.0.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:830994d7e1f31dd7e790045235605ab61cff6c94defc774547e8b7fdfbff3dc7"}, + {file = "pandas-3.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a64ce8b0f2de1d2efd2ae40b0abe7f8ae6b29fbfb3812098ed5a6f8e235ad9bf"}, + {file = "pandas-3.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9832c2c69da24b602c32e0c7b1b508a03949c18ba08d4d9f1c1033426685b447"}, + {file = "pandas-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:84f0904a69e7365f79a0c77d3cdfccbfb05bf87847e3a51a41e1426b0edb9c79"}, + {file = "pandas-3.0.1-cp311-cp311-win_arm64.whl", hash = "sha256:4a68773d5a778afb31d12e34f7dd4612ab90de8c6fb1d8ffe5d4a03b955082a1"}, + {file = "pandas-3.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:476f84f8c20c9f5bc47252b66b4bb25e1a9fc2fa98cead96744d8116cb85771d"}, + {file = "pandas-3.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0ab749dfba921edf641d4036c4c21c0b3ea70fea478165cb98a998fb2a261955"}, + {file = "pandas-3.0.1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b8e36891080b87823aff3640c78649b91b8ff6eea3c0d70aeabd72ea43ab069b"}, + {file = "pandas-3.0.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:532527a701281b9dd371e2f582ed9094f4c12dd9ffb82c0c54ee28d8ac9520c4"}, + {file = "pandas-3.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:356e5c055ed9b0da1580d465657bc7d00635af4fd47f30afb23025352ba764d1"}, + {file = "pandas-3.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9d810036895f9ad6345b8f2a338dd6998a74e8483847403582cab67745bff821"}, + {file = "pandas-3.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:536232a5fe26dd989bd633e7a0c450705fdc86a207fec7254a55e9a22950fe43"}, + {file = "pandas-3.0.1-cp312-cp312-win_arm64.whl", hash = "sha256:0f463ebfd8de7f326d38037c7363c6dacb857c5881ab8961fb387804d6daf2f7"}, + {file = "pandas-3.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5272627187b5d9c20e55d27caf5f2cd23e286aba25cadf73c8590e432e2b7262"}, + {file = "pandas-3.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:661e0f665932af88c7877f31da0dc743fe9c8f2524bdffe23d24fdcb67ef9d56"}, + {file = "pandas-3.0.1-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:75e6e292ff898679e47a2199172593d9f6107fd2dd3617c22c2946e97d5df46e"}, + {file = "pandas-3.0.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1ff8cf1d2896e34343197685f432450ec99a85ba8d90cce2030c5eee2ef98791"}, + {file = "pandas-3.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:eca8b4510f6763f3d37359c2105df03a7a221a508f30e396a51d0713d462e68a"}, + {file = "pandas-3.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:06aff2ad6f0b94a17822cf8b83bbb563b090ed82ff4fe7712db2ce57cd50d9b8"}, + {file = "pandas-3.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:9fea306c783e28884c29057a1d9baa11a349bbf99538ec1da44c8476563d1b25"}, + {file = "pandas-3.0.1-cp313-cp313-win_arm64.whl", hash = "sha256:a8d37a43c52917427e897cb2e429f67a449327394396a81034a4449b99afda59"}, + {file = "pandas-3.0.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d54855f04f8246ed7b6fc96b05d4871591143c46c0b6f4af874764ed0d2d6f06"}, + {file = "pandas-3.0.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4e1b677accee34a09e0dc2ce5624e4a58a1870ffe56fc021e9caf7f23cd7668f"}, + {file = "pandas-3.0.1-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a9cabbdcd03f1b6cd254d6dda8ae09b0252524be1592594c00b7895916cb1324"}, + {file = "pandas-3.0.1-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ae2ab1f166668b41e770650101e7090824fd34d17915dd9cd479f5c5e0065e9"}, + {file = "pandas-3.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6bf0603c2e30e2cafac32807b06435f28741135cb8697eae8b28c7d492fc7d76"}, + {file = "pandas-3.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6c426422973973cae1f4a23e51d4ae85974f44871b24844e4f7de752dd877098"}, + {file = "pandas-3.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b03f91ae8c10a85c1613102c7bef5229b5379f343030a3ccefeca8a33414cf35"}, + {file = "pandas-3.0.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:99d0f92ed92d3083d140bf6b97774f9f13863924cf3f52a70711f4e7588f9d0a"}, + {file = "pandas-3.0.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3b66857e983208654294bb6477b8a63dee26b37bdd0eb34d010556e91261784f"}, + {file = "pandas-3.0.1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:56cf59638bf24dc9bdf2154c81e248b3289f9a09a6d04e63608c159022352749"}, + {file = "pandas-3.0.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c1a9f55e0f46951874b863d1f3906dcb57df2d9be5c5847ba4dfb55b2c815249"}, + {file = "pandas-3.0.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1849f0bba9c8a2fb0f691d492b834cc8dadf617e29015c66e989448d58d011ee"}, + {file = "pandas-3.0.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c3d288439e11b5325b02ae6e9cc83e6805a62c40c5a6220bea9beb899c073b1c"}, + {file = "pandas-3.0.1-cp314-cp314-win_amd64.whl", hash = "sha256:93325b0fe372d192965f4cca88d97667f49557398bbf94abdda3bf1b591dbe66"}, + {file = "pandas-3.0.1-cp314-cp314-win_arm64.whl", hash = "sha256:97ca08674e3287c7148f4858b01136f8bdfe7202ad25ad04fec602dd1d29d132"}, + {file = "pandas-3.0.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:58eeb1b2e0fb322befcf2bbc9ba0af41e616abadb3d3414a6bc7167f6cbfce32"}, + {file = "pandas-3.0.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:cd9af1276b5ca9e298bd79a26bda32fa9cc87ed095b2a9a60978d2ca058eaf87"}, + {file = "pandas-3.0.1-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:94f87a04984d6b63788327cd9f79dda62b7f9043909d2440ceccf709249ca988"}, + {file = "pandas-3.0.1-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85fe4c4df62e1e20f9db6ebfb88c844b092c22cd5324bdcf94bfa2fc1b391221"}, + {file = "pandas-3.0.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:331ca75a2f8672c365ae25c0b29e46f5ac0c6551fdace8eec4cd65e4fac271ff"}, + {file = "pandas-3.0.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:15860b1fdb1973fffade772fdb931ccf9b2f400a3f5665aef94a00445d7d8dd5"}, + {file = "pandas-3.0.1-cp314-cp314t-win_amd64.whl", hash = "sha256:44f1364411d5670efa692b146c748f4ed013df91ee91e9bec5677fb1fd58b937"}, + {file = "pandas-3.0.1-cp314-cp314t-win_arm64.whl", hash = "sha256:108dd1790337a494aa80e38def654ca3f0968cf4f362c85f44c15e471667102d"}, + {file = "pandas-3.0.1.tar.gz", hash = "sha256:4186a699674af418f655dbd420ed87f50d56b4cd6603784279d9eef6627823c8"}, ] [package.dependencies] -numpy = {version = ">=1.26.0", markers = "python_version >= \"3.12\""} +numpy = [ + {version = ">=1.26.0", markers = "python_version < \"3.14\""}, + {version = ">=2.3.3", markers = "python_version >= \"3.14\""}, +] python-dateutil = ">=2.8.2" -pytz = ">=2020.1" -tzdata = ">=2022.7" +tzdata = {version = "*", markers = "sys_platform == \"win32\" or sys_platform == \"emscripten\""} [package.extras] -all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"] -aws = ["s3fs (>=2022.11.0)"] -clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"] -compression = ["zstandard (>=0.19.0)"] -computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"] -consortium-standard = ["dataframe-api-compat (>=0.1.7)"] -excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"] -feather = ["pyarrow (>=10.0.1)"] -fss = ["fsspec (>=2022.11.0)"] -gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"] -hdf5 = ["tables (>=3.8.0)"] -html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"] -mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"] -output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"] -parquet = ["pyarrow (>=10.0.1)"] -performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"] -plot = ["matplotlib (>=3.6.3)"] -postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"] -pyarrow = ["pyarrow (>=10.0.1)"] -spss = ["pyreadstat (>=1.2.0)"] -sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"] -test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] -xml = ["lxml (>=4.9.2)"] +all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.36)", "adbc-driver-postgresql (>=1.2.0)", "adbc-driver-sqlite (>=1.2.0)", "beautifulsoup4 (>=4.12.3)", "bottleneck (>=1.4.2)", "fastparquet (>=2024.11.0)", "fsspec (>=2024.10.0)", "gcsfs (>=2024.10.0)", "html5lib (>=1.1)", "hypothesis (>=6.116.0)", "jinja2 (>=3.1.5)", "lxml (>=5.3.0)", "matplotlib (>=3.9.3)", "numba (>=0.60.0)", "numexpr (>=2.10.2)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.5)", "psycopg2 (>=2.9.10)", "pyarrow (>=13.0.0)", "pyiceberg (>=0.8.1)", "pymysql (>=1.1.1)", "pyreadstat (>=1.2.8)", "pytest (>=8.3.4)", "pytest-xdist (>=3.6.1)", "python-calamine (>=0.3.0)", "pytz (>=2024.2)", "pyxlsb (>=1.0.10)", "qtpy (>=2.4.2)", "s3fs (>=2024.10.0)", "scipy (>=1.14.1)", "tables (>=3.10.1)", "tabulate (>=0.9.0)", "xarray (>=2024.10.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.2.0)", "zstandard (>=0.23.0)"] +aws = ["s3fs (>=2024.10.0)"] +clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.4.2)"] +compression = ["zstandard (>=0.23.0)"] +computation = ["scipy (>=1.14.1)", "xarray (>=2024.10.0)"] +excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.5)", "python-calamine (>=0.3.0)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.2.0)"] +feather = ["pyarrow (>=13.0.0)"] +fss = ["fsspec (>=2024.10.0)"] +gcp = ["gcsfs (>=2024.10.0)"] +hdf5 = ["tables (>=3.10.1)"] +html = ["beautifulsoup4 (>=4.12.3)", "html5lib (>=1.1)", "lxml (>=5.3.0)"] +iceberg = ["pyiceberg (>=0.8.1)"] +mysql = ["SQLAlchemy (>=2.0.36)", "pymysql (>=1.1.1)"] +output-formatting = ["jinja2 (>=3.1.5)", "tabulate (>=0.9.0)"] +parquet = ["pyarrow (>=13.0.0)"] +performance = ["bottleneck (>=1.4.2)", "numba (>=0.60.0)", "numexpr (>=2.10.2)"] +plot = ["matplotlib (>=3.9.3)"] +postgresql = ["SQLAlchemy (>=2.0.36)", "adbc-driver-postgresql (>=1.2.0)", "psycopg2 (>=2.9.10)"] +pyarrow = ["pyarrow (>=13.0.0)"] +spss = ["pyreadstat (>=1.2.8)"] +sql-other = ["SQLAlchemy (>=2.0.36)", "adbc-driver-postgresql (>=1.2.0)", "adbc-driver-sqlite (>=1.2.0)"] +test = ["hypothesis (>=6.116.0)", "pytest (>=8.3.4)", "pytest-xdist (>=3.6.1)"] +timezone = ["pytz (>=2024.2)"] +xml = ["lxml (>=5.3.0)"] [[package]] name = "pathspec" -version = "0.12.1" +version = "1.0.4" description = "Utility library for gitignore style pattern matching of file paths." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, - {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, + {file = "pathspec-1.0.4-py3-none-any.whl", hash = "sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723"}, + {file = "pathspec-1.0.4.tar.gz", hash = "sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645"}, ] +[package.extras] +hyperscan = ["hyperscan (>=0.7)"] +optional = ["typing-extensions (>=4)"] +re2 = ["google-re2 (>=1.1)"] +tests = ["pytest (>=9)", "typing-extensions (>=4.15)"] + [[package]] name = "pbr" version = "6.1.1" @@ -1308,91 +1940,111 @@ setuptools = "*" [[package]] name = "pillow" -version = "11.1.0" -description = "Python Imaging Library (Fork)" +version = "12.1.1" +description = "Python Imaging Library (fork)" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["main"] files = [ - {file = "pillow-11.1.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:e1abe69aca89514737465752b4bcaf8016de61b3be1397a8fc260ba33321b3a8"}, - {file = "pillow-11.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c640e5a06869c75994624551f45e5506e4256562ead981cce820d5ab39ae2192"}, - {file = "pillow-11.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a07dba04c5e22824816b2615ad7a7484432d7f540e6fa86af60d2de57b0fcee2"}, - {file = "pillow-11.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e267b0ed063341f3e60acd25c05200df4193e15a4a5807075cd71225a2386e26"}, - {file = "pillow-11.1.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:bd165131fd51697e22421d0e467997ad31621b74bfc0b75956608cb2906dda07"}, - {file = "pillow-11.1.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:abc56501c3fd148d60659aae0af6ddc149660469082859fa7b066a298bde9482"}, - {file = "pillow-11.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:54ce1c9a16a9561b6d6d8cb30089ab1e5eb66918cb47d457bd996ef34182922e"}, - {file = "pillow-11.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:73ddde795ee9b06257dac5ad42fcb07f3b9b813f8c1f7f870f402f4dc54b5269"}, - {file = "pillow-11.1.0-cp310-cp310-win32.whl", hash = "sha256:3a5fe20a7b66e8135d7fd617b13272626a28278d0e578c98720d9ba4b2439d49"}, - {file = "pillow-11.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:b6123aa4a59d75f06e9dd3dac5bf8bc9aa383121bb3dd9a7a612e05eabc9961a"}, - {file = "pillow-11.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:a76da0a31da6fcae4210aa94fd779c65c75786bc9af06289cd1c184451ef7a65"}, - {file = "pillow-11.1.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:e06695e0326d05b06833b40b7ef477e475d0b1ba3a6d27da1bb48c23209bf457"}, - {file = "pillow-11.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:96f82000e12f23e4f29346e42702b6ed9a2f2fea34a740dd5ffffcc8c539eb35"}, - {file = "pillow-11.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3cd561ded2cf2bbae44d4605837221b987c216cff94f49dfeed63488bb228d2"}, - {file = "pillow-11.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f189805c8be5ca5add39e6f899e6ce2ed824e65fb45f3c28cb2841911da19070"}, - {file = "pillow-11.1.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:dd0052e9db3474df30433f83a71b9b23bd9e4ef1de13d92df21a52c0303b8ab6"}, - {file = "pillow-11.1.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:837060a8599b8f5d402e97197d4924f05a2e0d68756998345c829c33186217b1"}, - {file = "pillow-11.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:aa8dd43daa836b9a8128dbe7d923423e5ad86f50a7a14dc688194b7be5c0dea2"}, - {file = "pillow-11.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0a2f91f8a8b367e7a57c6e91cd25af510168091fb89ec5146003e424e1558a96"}, - {file = "pillow-11.1.0-cp311-cp311-win32.whl", hash = "sha256:c12fc111ef090845de2bb15009372175d76ac99969bdf31e2ce9b42e4b8cd88f"}, - {file = "pillow-11.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:fbd43429d0d7ed6533b25fc993861b8fd512c42d04514a0dd6337fb3ccf22761"}, - {file = "pillow-11.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:f7955ecf5609dee9442cbface754f2c6e541d9e6eda87fad7f7a989b0bdb9d71"}, - {file = "pillow-11.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2062ffb1d36544d42fcaa277b069c88b01bb7298f4efa06731a7fd6cc290b81a"}, - {file = "pillow-11.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a85b653980faad27e88b141348707ceeef8a1186f75ecc600c395dcac19f385b"}, - {file = "pillow-11.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9409c080586d1f683df3f184f20e36fb647f2e0bc3988094d4fd8c9f4eb1b3b3"}, - {file = "pillow-11.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7fdadc077553621911f27ce206ffcbec7d3f8d7b50e0da39f10997e8e2bb7f6a"}, - {file = "pillow-11.1.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:93a18841d09bcdd774dcdc308e4537e1f867b3dec059c131fde0327899734aa1"}, - {file = "pillow-11.1.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9aa9aeddeed452b2f616ff5507459e7bab436916ccb10961c4a382cd3e03f47f"}, - {file = "pillow-11.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3cdcdb0b896e981678eee140d882b70092dac83ac1cdf6b3a60e2216a73f2b91"}, - {file = "pillow-11.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:36ba10b9cb413e7c7dfa3e189aba252deee0602c86c309799da5a74009ac7a1c"}, - {file = "pillow-11.1.0-cp312-cp312-win32.whl", hash = "sha256:cfd5cd998c2e36a862d0e27b2df63237e67273f2fc78f47445b14e73a810e7e6"}, - {file = "pillow-11.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:a697cd8ba0383bba3d2d3ada02b34ed268cb548b369943cd349007730c92bddf"}, - {file = "pillow-11.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:4dd43a78897793f60766563969442020e90eb7847463eca901e41ba186a7d4a5"}, - {file = "pillow-11.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ae98e14432d458fc3de11a77ccb3ae65ddce70f730e7c76140653048c71bfcbc"}, - {file = "pillow-11.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cc1331b6d5a6e144aeb5e626f4375f5b7ae9934ba620c0ac6b3e43d5e683a0f0"}, - {file = "pillow-11.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:758e9d4ef15d3560214cddbc97b8ef3ef86ce04d62ddac17ad39ba87e89bd3b1"}, - {file = "pillow-11.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b523466b1a31d0dcef7c5be1f20b942919b62fd6e9a9be199d035509cbefc0ec"}, - {file = "pillow-11.1.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:9044b5e4f7083f209c4e35aa5dd54b1dd5b112b108648f5c902ad586d4f945c5"}, - {file = "pillow-11.1.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:3764d53e09cdedd91bee65c2527815d315c6b90d7b8b79759cc48d7bf5d4f114"}, - {file = "pillow-11.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:31eba6bbdd27dde97b0174ddf0297d7a9c3a507a8a1480e1e60ef914fe23d352"}, - {file = "pillow-11.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b5d658fbd9f0d6eea113aea286b21d3cd4d3fd978157cbf2447a6035916506d3"}, - {file = "pillow-11.1.0-cp313-cp313-win32.whl", hash = "sha256:f86d3a7a9af5d826744fabf4afd15b9dfef44fe69a98541f666f66fbb8d3fef9"}, - {file = "pillow-11.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:593c5fd6be85da83656b93ffcccc2312d2d149d251e98588b14fbc288fd8909c"}, - {file = "pillow-11.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:11633d58b6ee5733bde153a8dafd25e505ea3d32e261accd388827ee987baf65"}, - {file = "pillow-11.1.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:70ca5ef3b3b1c4a0812b5c63c57c23b63e53bc38e758b37a951e5bc466449861"}, - {file = "pillow-11.1.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8000376f139d4d38d6851eb149b321a52bb8893a88dae8ee7d95840431977081"}, - {file = "pillow-11.1.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ee85f0696a17dd28fbcfceb59f9510aa71934b483d1f5601d1030c3c8304f3c"}, - {file = "pillow-11.1.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:dd0e081319328928531df7a0e63621caf67652c8464303fd102141b785ef9547"}, - {file = "pillow-11.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e63e4e5081de46517099dc30abe418122f54531a6ae2ebc8680bcd7096860eab"}, - {file = "pillow-11.1.0-cp313-cp313t-win32.whl", hash = "sha256:dda60aa465b861324e65a78c9f5cf0f4bc713e4309f83bc387be158b077963d9"}, - {file = "pillow-11.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ad5db5781c774ab9a9b2c4302bbf0c1014960a0a7be63278d13ae6fdf88126fe"}, - {file = "pillow-11.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:67cd427c68926108778a9005f2a04adbd5e67c442ed21d95389fe1d595458756"}, - {file = "pillow-11.1.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:bf902d7413c82a1bfa08b06a070876132a5ae6b2388e2712aab3a7cbc02205c6"}, - {file = "pillow-11.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c1eec9d950b6fe688edee07138993e54ee4ae634c51443cfb7c1e7613322718e"}, - {file = "pillow-11.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e275ee4cb11c262bd108ab2081f750db2a1c0b8c12c1897f27b160c8bd57bbc"}, - {file = "pillow-11.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4db853948ce4e718f2fc775b75c37ba2efb6aaea41a1a5fc57f0af59eee774b2"}, - {file = "pillow-11.1.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:ab8a209b8485d3db694fa97a896d96dd6533d63c22829043fd9de627060beade"}, - {file = "pillow-11.1.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:54251ef02a2309b5eec99d151ebf5c9904b77976c8abdcbce7891ed22df53884"}, - {file = "pillow-11.1.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5bb94705aea800051a743aa4874bb1397d4695fb0583ba5e425ee0328757f196"}, - {file = "pillow-11.1.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:89dbdb3e6e9594d512780a5a1c42801879628b38e3efc7038094430844e271d8"}, - {file = "pillow-11.1.0-cp39-cp39-win32.whl", hash = "sha256:e5449ca63da169a2e6068dd0e2fcc8d91f9558aba89ff6d02121ca8ab11e79e5"}, - {file = "pillow-11.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:3362c6ca227e65c54bf71a5f88b3d4565ff1bcbc63ae72c34b07bbb1cc59a43f"}, - {file = "pillow-11.1.0-cp39-cp39-win_arm64.whl", hash = "sha256:b20be51b37a75cc54c2c55def3fa2c65bb94ba859dde241cd0a4fd302de5ae0a"}, - {file = "pillow-11.1.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:8c730dc3a83e5ac137fbc92dfcfe1511ce3b2b5d7578315b63dbbb76f7f51d90"}, - {file = "pillow-11.1.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:7d33d2fae0e8b170b6a6c57400e077412240f6f5bb2a342cf1ee512a787942bb"}, - {file = "pillow-11.1.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a8d65b38173085f24bc07f8b6c505cbb7418009fa1a1fcb111b1f4961814a442"}, - {file = "pillow-11.1.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:015c6e863faa4779251436db398ae75051469f7c903b043a48f078e437656f83"}, - {file = "pillow-11.1.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d44ff19eea13ae4acdaaab0179fa68c0c6f2f45d66a4d8ec1eda7d6cecbcc15f"}, - {file = "pillow-11.1.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d3d8da4a631471dfaf94c10c85f5277b1f8e42ac42bade1ac67da4b4a7359b73"}, - {file = "pillow-11.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:4637b88343166249fe8aa94e7c4a62a180c4b3898283bb5d3d2fd5fe10d8e4e0"}, - {file = "pillow-11.1.0.tar.gz", hash = "sha256:368da70808b36d73b4b390a8ffac11069f8a5c85f29eff1f1b01bcf3ef5b2a20"}, + {file = "pillow-12.1.1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1f1625b72740fdda5d77b4def688eb8fd6490975d06b909fd19f13f391e077e0"}, + {file = "pillow-12.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:178aa072084bd88ec759052feca8e56cbb14a60b39322b99a049e58090479713"}, + {file = "pillow-12.1.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b66e95d05ba806247aaa1561f080abc7975daf715c30780ff92a20e4ec546e1b"}, + {file = "pillow-12.1.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:89c7e895002bbe49cdc5426150377cbbc04767d7547ed145473f496dfa40408b"}, + {file = "pillow-12.1.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a5cbdcddad0af3da87cb16b60d23648bc3b51967eb07223e9fed77a82b457c4"}, + {file = "pillow-12.1.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9f51079765661884a486727f0729d29054242f74b46186026582b4e4769918e4"}, + {file = "pillow-12.1.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:99c1506ea77c11531d75e3a412832a13a71c7ebc8192ab9e4b2e355555920e3e"}, + {file = "pillow-12.1.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:36341d06738a9f66c8287cf8b876d24b18db9bd8740fa0672c74e259ad408cff"}, + {file = "pillow-12.1.1-cp310-cp310-win32.whl", hash = "sha256:6c52f062424c523d6c4db85518774cc3d50f5539dd6eed32b8f6229b26f24d40"}, + {file = "pillow-12.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:c6008de247150668a705a6338156efb92334113421ceecf7438a12c9a12dab23"}, + {file = "pillow-12.1.1-cp310-cp310-win_arm64.whl", hash = "sha256:1a9b0ee305220b392e1124a764ee4265bd063e54a751a6b62eff69992f457fa9"}, + {file = "pillow-12.1.1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:e879bb6cd5c73848ef3b2b48b8af9ff08c5b71ecda8048b7dd22d8a33f60be32"}, + {file = "pillow-12.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:365b10bb9417dd4498c0e3b128018c4a624dc11c7b97d8cc54effe3b096f4c38"}, + {file = "pillow-12.1.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d4ce8e329c93845720cd2014659ca67eac35f6433fd3050393d85f3ecef0dad5"}, + {file = "pillow-12.1.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc354a04072b765eccf2204f588a7a532c9511e8b9c7f900e1b64e3e33487090"}, + {file = "pillow-12.1.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7e7976bf1910a8116b523b9f9f58bf410f3e8aa330cd9a2bb2953f9266ab49af"}, + {file = "pillow-12.1.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:597bd9c8419bc7c6af5604e55847789b69123bbe25d65cc6ad3012b4f3c98d8b"}, + {file = "pillow-12.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2c1fc0f2ca5f96a3c8407e41cca26a16e46b21060fe6d5b099d2cb01412222f5"}, + {file = "pillow-12.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:578510d88c6229d735855e1f278aa305270438d36a05031dfaae5067cc8eb04d"}, + {file = "pillow-12.1.1-cp311-cp311-win32.whl", hash = "sha256:7311c0a0dcadb89b36b7025dfd8326ecfa36964e29913074d47382706e516a7c"}, + {file = "pillow-12.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:fbfa2a7c10cc2623f412753cddf391c7f971c52ca40a3f65dc5039b2939e8563"}, + {file = "pillow-12.1.1-cp311-cp311-win_arm64.whl", hash = "sha256:b81b5e3511211631b3f672a595e3221252c90af017e399056d0faabb9538aa80"}, + {file = "pillow-12.1.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ab323b787d6e18b3d91a72fc99b1a2c28651e4358749842b8f8dfacd28ef2052"}, + {file = "pillow-12.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:adebb5bee0f0af4909c30db0d890c773d1a92ffe83da908e2e9e720f8edf3984"}, + {file = "pillow-12.1.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bb66b7cc26f50977108790e2456b7921e773f23db5630261102233eb355a3b79"}, + {file = "pillow-12.1.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aee2810642b2898bb187ced9b349e95d2a7272930796e022efaf12e99dccd293"}, + {file = "pillow-12.1.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a0b1cd6232e2b618adcc54d9882e4e662a089d5768cd188f7c245b4c8c44a397"}, + {file = "pillow-12.1.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7aac39bcf8d4770d089588a2e1dd111cbaa42df5a94be3114222057d68336bd0"}, + {file = "pillow-12.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ab174cd7d29a62dd139c44bf74b698039328f45cb03b4596c43473a46656b2f3"}, + {file = "pillow-12.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:339ffdcb7cbeaa08221cd401d517d4b1fe7a9ed5d400e4a8039719238620ca35"}, + {file = "pillow-12.1.1-cp312-cp312-win32.whl", hash = "sha256:5d1f9575a12bed9e9eedd9a4972834b08c97a352bd17955ccdebfeca5913fa0a"}, + {file = "pillow-12.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:21329ec8c96c6e979cd0dfd29406c40c1d52521a90544463057d2aaa937d66a6"}, + {file = "pillow-12.1.1-cp312-cp312-win_arm64.whl", hash = "sha256:af9a332e572978f0218686636610555ae3defd1633597be015ed50289a03c523"}, + {file = "pillow-12.1.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:d242e8ac078781f1de88bf823d70c1a9b3c7950a44cdf4b7c012e22ccbcd8e4e"}, + {file = "pillow-12.1.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:02f84dfad02693676692746df05b89cf25597560db2857363a208e393429f5e9"}, + {file = "pillow-12.1.1-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:e65498daf4b583091ccbb2556c7000abf0f3349fcd57ef7adc9a84a394ed29f6"}, + {file = "pillow-12.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6c6db3b84c87d48d0088943bf33440e0c42370b99b1c2a7989216f7b42eede60"}, + {file = "pillow-12.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8b7e5304e34942bf62e15184219a7b5ad4ff7f3bb5cca4d984f37df1a0e1aee2"}, + {file = "pillow-12.1.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:18e5bddd742a44b7e6b1e773ab5db102bd7a94c32555ba656e76d319d19c3850"}, + {file = "pillow-12.1.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc44ef1f3de4f45b50ccf9136999d71abb99dca7706bc75d222ed350b9fd2289"}, + {file = "pillow-12.1.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5a8eb7ed8d4198bccbd07058416eeec51686b498e784eda166395a23eb99138e"}, + {file = "pillow-12.1.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:47b94983da0c642de92ced1702c5b6c292a84bd3a8e1d1702ff923f183594717"}, + {file = "pillow-12.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:518a48c2aab7ce596d3bf79d0e275661b846e86e4d0e7dec34712c30fe07f02a"}, + {file = "pillow-12.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a550ae29b95c6dc13cf69e2c9dc5747f814c54eeb2e32d683e5e93af56caa029"}, + {file = "pillow-12.1.1-cp313-cp313-win32.whl", hash = "sha256:a003d7422449f6d1e3a34e3dd4110c22148336918ddbfc6a32581cd54b2e0b2b"}, + {file = "pillow-12.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:344cf1e3dab3be4b1fa08e449323d98a2a3f819ad20f4b22e77a0ede31f0faa1"}, + {file = "pillow-12.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:5c0dd1636633e7e6a0afe7bf6a51a14992b7f8e60de5789018ebbdfae55b040a"}, + {file = "pillow-12.1.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0330d233c1a0ead844fc097a7d16c0abff4c12e856c0b325f231820fee1f39da"}, + {file = "pillow-12.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5dae5f21afb91322f2ff791895ddd8889e5e947ff59f71b46041c8ce6db790bc"}, + {file = "pillow-12.1.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2e0c664be47252947d870ac0d327fea7e63985a08794758aa8af5b6cb6ec0c9c"}, + {file = "pillow-12.1.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:691ab2ac363b8217f7d31b3497108fb1f50faab2f75dfb03284ec2f217e87bf8"}, + {file = "pillow-12.1.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9e8064fb1cc019296958595f6db671fba95209e3ceb0c4734c9baf97de04b20"}, + {file = "pillow-12.1.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:472a8d7ded663e6162dafdf20015c486a7009483ca671cece7a9279b512fcb13"}, + {file = "pillow-12.1.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:89b54027a766529136a06cfebeecb3a04900397a3590fd252160b888479517bf"}, + {file = "pillow-12.1.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:86172b0831b82ce4f7877f280055892b31179e1576aa00d0df3bb1bbf8c3e524"}, + {file = "pillow-12.1.1-cp313-cp313t-win32.whl", hash = "sha256:44ce27545b6efcf0fdbdceb31c9a5bdea9333e664cda58a7e674bb74608b3986"}, + {file = "pillow-12.1.1-cp313-cp313t-win_amd64.whl", hash = "sha256:a285e3eb7a5a45a2ff504e31f4a8d1b12ef62e84e5411c6804a42197c1cf586c"}, + {file = "pillow-12.1.1-cp313-cp313t-win_arm64.whl", hash = "sha256:cc7d296b5ea4d29e6570dabeaed58d31c3fea35a633a69679fb03d7664f43fb3"}, + {file = "pillow-12.1.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:417423db963cb4be8bac3fc1204fe61610f6abeed1580a7a2cbb2fbda20f12af"}, + {file = "pillow-12.1.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:b957b71c6b2387610f556a7eb0828afbe40b4a98036fc0d2acfa5a44a0c2036f"}, + {file = "pillow-12.1.1-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:097690ba1f2efdeb165a20469d59d8bb03c55fb6621eb2041a060ae8ea3e9642"}, + {file = "pillow-12.1.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2815a87ab27848db0321fb78c7f0b2c8649dee134b7f2b80c6a45c6831d75ccd"}, + {file = "pillow-12.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f7ed2c6543bad5a7d5530eb9e78c53132f93dfa44a28492db88b41cdab885202"}, + {file = "pillow-12.1.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:652a2c9ccfb556235b2b501a3a7cf3742148cd22e04b5625c5fe057ea3e3191f"}, + {file = "pillow-12.1.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d6e4571eedf43af33d0fc233a382a76e849badbccdf1ac438841308652a08e1f"}, + {file = "pillow-12.1.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b574c51cf7d5d62e9be37ba446224b59a2da26dc4c1bb2ecbe936a4fb1a7cb7f"}, + {file = "pillow-12.1.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a37691702ed687799de29a518d63d4682d9016932db66d4e90c345831b02fb4e"}, + {file = "pillow-12.1.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f95c00d5d6700b2b890479664a06e754974848afaae5e21beb4d83c106923fd0"}, + {file = "pillow-12.1.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:559b38da23606e68681337ad74622c4dbba02254fc9cb4488a305dd5975c7eeb"}, + {file = "pillow-12.1.1-cp314-cp314-win32.whl", hash = "sha256:03edcc34d688572014ff223c125a3f77fb08091e4607e7745002fc214070b35f"}, + {file = "pillow-12.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:50480dcd74fa63b8e78235957d302d98d98d82ccbfac4c7e12108ba9ecbdba15"}, + {file = "pillow-12.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:5cb1785d97b0c3d1d1a16bc1d710c4a0049daefc4935f3a8f31f827f4d3d2e7f"}, + {file = "pillow-12.1.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1f90cff8aa76835cba5769f0b3121a22bd4eb9e6884cfe338216e557a9a548b8"}, + {file = "pillow-12.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1f1be78ce9466a7ee64bfda57bdba0f7cc499d9794d518b854816c41bf0aa4e9"}, + {file = "pillow-12.1.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:42fc1f4677106188ad9a55562bbade416f8b55456f522430fadab3cef7cd4e60"}, + {file = "pillow-12.1.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:98edb152429ab62a1818039744d8fbb3ccab98a7c29fc3d5fcef158f3f1f68b7"}, + {file = "pillow-12.1.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d470ab1178551dd17fdba0fef463359c41aaa613cdcd7ff8373f54be629f9f8f"}, + {file = "pillow-12.1.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6408a7b064595afcab0a49393a413732a35788f2a5092fdc6266952ed67de586"}, + {file = "pillow-12.1.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5d8c41325b382c07799a3682c1c258469ea2ff97103c53717b7893862d0c98ce"}, + {file = "pillow-12.1.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c7697918b5be27424e9ce568193efd13d925c4481dd364e43f5dff72d33e10f8"}, + {file = "pillow-12.1.1-cp314-cp314t-win32.whl", hash = "sha256:d2912fd8114fc5545aa3a4b5576512f64c55a03f3ebcca4c10194d593d43ea36"}, + {file = "pillow-12.1.1-cp314-cp314t-win_amd64.whl", hash = "sha256:4ceb838d4bd9dab43e06c363cab2eebf63846d6a4aeaea283bbdfd8f1a8ed58b"}, + {file = "pillow-12.1.1-cp314-cp314t-win_arm64.whl", hash = "sha256:7b03048319bfc6170e93bd60728a1af51d3dd7704935feb228c4d4faab35d334"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:600fd103672b925fe62ed08e0d874ea34d692474df6f4bf7ebe148b30f89f39f"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:665e1b916b043cef294bc54d47bf02d87e13f769bc4bc5fa225a24b3a6c5aca9"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:495c302af3aad1ca67420ddd5c7bd480c8867ad173528767d906428057a11f0e"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8fd420ef0c52c88b5a035a0886f367748c72147b2b8f384c9d12656678dfdfa9"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f975aa7ef9684ce7e2c18a3aa8f8e2106ce1e46b94ab713d156b2898811651d3"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8089c852a56c2966cf18835db62d9b34fef7ba74c726ad943928d494fa7f4735"}, + {file = "pillow-12.1.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:cb9bb857b2d057c6dfc72ac5f3b44836924ba15721882ef103cecb40d002d80e"}, + {file = "pillow-12.1.1.tar.gz", hash = "sha256:9ad8fa5937ab05218e2b6a4cff30295ad35afd2f83ac592e68c0d871bb0fdbc4"}, ] [package.extras] -docs = ["furo", "olefile", "sphinx (>=8.1)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] +docs = ["furo", "olefile", "sphinx (>=8.2)", "sphinx-autobuild", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"] fpx = ["olefile"] mic = ["olefile"] -tests = ["check-manifest", "coverage (>=7.4.2)", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout", "trove-classifiers (>=2024.10.12)"] -typing = ["typing-extensions ; python_version < \"3.10\""] +test-arrow = ["arro3-compute", "arro3-core", "nanoarrow", "pyarrow"] +tests = ["check-manifest", "coverage (>=7.4.2)", "defusedxml", "markdown2", "olefile", "packaging", "pyroma (>=5)", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "trove-classifiers (>=2024.10.12)"] xmp = ["defusedxml"] [[package]] @@ -1428,6 +2080,37 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "psutil" +version = "6.1.1" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +groups = ["main"] +files = [ + {file = "psutil-6.1.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:9ccc4316f24409159897799b83004cb1e24f9819b0dcf9c0b68bdcb6cefee6a8"}, + {file = "psutil-6.1.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ca9609c77ea3b8481ab005da74ed894035936223422dc591d6772b147421f777"}, + {file = "psutil-6.1.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:8df0178ba8a9e5bc84fed9cfa61d54601b371fbec5c8eebad27575f1e105c0d4"}, + {file = "psutil-6.1.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:1924e659d6c19c647e763e78670a05dbb7feaf44a0e9c94bf9e14dfc6ba50468"}, + {file = "psutil-6.1.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:018aeae2af92d943fdf1da6b58665124897cfc94faa2ca92098838f83e1b1bca"}, + {file = "psutil-6.1.1-cp27-none-win32.whl", hash = "sha256:6d4281f5bbca041e2292be3380ec56a9413b790579b8e593b1784499d0005dac"}, + {file = "psutil-6.1.1-cp27-none-win_amd64.whl", hash = "sha256:c777eb75bb33c47377c9af68f30e9f11bc78e0f07fbf907be4a5d70b2fe5f030"}, + {file = "psutil-6.1.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:fc0ed7fe2231a444fc219b9c42d0376e0a9a1a72f16c5cfa0f68d19f1a0663e8"}, + {file = "psutil-6.1.1-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0bdd4eab935276290ad3cb718e9809412895ca6b5b334f5a9111ee6d9aff9377"}, + {file = "psutil-6.1.1-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6e06c20c05fe95a3d7302d74e7097756d4ba1247975ad6905441ae1b5b66003"}, + {file = "psutil-6.1.1-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97f7cb9921fbec4904f522d972f0c0e1f4fabbdd4e0287813b21215074a0f160"}, + {file = "psutil-6.1.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33431e84fee02bc84ea36d9e2c4a6d395d479c9dd9bba2376c1f6ee8f3a4e0b3"}, + {file = "psutil-6.1.1-cp36-cp36m-win32.whl", hash = "sha256:384636b1a64b47814437d1173be1427a7c83681b17a450bfc309a1953e329603"}, + {file = "psutil-6.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:8be07491f6ebe1a693f17d4f11e69d0dc1811fa082736500f649f79df7735303"}, + {file = "psutil-6.1.1-cp37-abi3-win32.whl", hash = "sha256:eaa912e0b11848c4d9279a93d7e2783df352b082f40111e078388701fd479e53"}, + {file = "psutil-6.1.1-cp37-abi3-win_amd64.whl", hash = "sha256:f35cfccb065fff93529d2afb4a2e89e363fe63ca1e4a5da22b603a85833c2649"}, + {file = "psutil-6.1.1.tar.gz", hash = "sha256:cf8496728c18f2d0b45198f06895be52f36611711746b7f30c464b422b50e2f5"}, +] + +[package.extras] +dev = ["abi3audit", "black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest-cov", "requests", "rstcheck", "ruff", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "vulture", "wheel"] +test = ["pytest", "pytest-xdist", "setuptools"] + [[package]] name = "pycparser" version = "2.22" @@ -1435,6 +2118,7 @@ description = "C parser in Python" optional = false python-versions = ">=3.8" groups = ["main"] +markers = "implementation_name != \"PyPy\"" files = [ {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, @@ -1457,21 +2141,24 @@ windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pyjwt" -version = "2.10.1" +version = "2.11.0" description = "JSON Web Token implementation in Python" optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, - {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, + {file = "pyjwt-2.11.0-py3-none-any.whl", hash = "sha256:94a6bde30eb5c8e04fee991062b534071fd1439ef58d2adc9ccb823e7bcd0469"}, + {file = "pyjwt-2.11.0.tar.gz", hash = "sha256:35f95c1f0fbe5d5ba6e43f00271c275f7a1a4db1dab27bf708073b75318ea623"}, ] +[package.dependencies] +cryptography = {version = ">=3.4.0", optional = true, markers = "extra == \"crypto\""} + [package.extras] crypto = ["cryptography (>=3.4.0)"] -dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx", "sphinx-rtd-theme", "zope.interface"] +dev = ["coverage[toml] (==7.10.7)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=8.4.2,<9.0.0)", "sphinx", "sphinx-rtd-theme", "zope.interface"] docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] -tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] +tests = ["coverage[toml] (==7.10.7)", "pytest (>=8.4.2,<9.0.0)"] [[package]] name = "pyparsing" @@ -1525,17 +2212,60 @@ files = [ six = ">=1.5" [[package]] -name = "pytz" -version = "2025.1" -description = "World timezone definitions, modern and historical" +name = "pytokens" +version = "0.4.1" +description = "A Fast, spec compliant Python 3.14+ tokenizer that runs on older Pythons." optional = false -python-versions = "*" -groups = ["main"] +python-versions = ">=3.8" +groups = ["dev"] files = [ - {file = "pytz-2025.1-py2.py3-none-any.whl", hash = "sha256:89dd22dca55b46eac6eda23b2d72721bf1bdfef212645d81513ef5d03038de57"}, - {file = "pytz-2025.1.tar.gz", hash = "sha256:c2db42be2a2518b28e65f9207c4d05e6ff547d1efa4086469ef855e4ab70178e"}, + {file = "pytokens-0.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2a44ed93ea23415c54f3face3b65ef2b844d96aeb3455b8a69b3df6beab6acc5"}, + {file = "pytokens-0.4.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:add8bf86b71a5d9fb5b89f023a80b791e04fba57960aa790cc6125f7f1d39dfe"}, + {file = "pytokens-0.4.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:670d286910b531c7b7e3c0b453fd8156f250adb140146d234a82219459b9640c"}, + {file = "pytokens-0.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4e691d7f5186bd2842c14813f79f8884bb03f5995f0575272009982c5ac6c0f7"}, + {file = "pytokens-0.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:27b83ad28825978742beef057bfe406ad6ed524b2d28c252c5de7b4a6dd48fa2"}, + {file = "pytokens-0.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d70e77c55ae8380c91c0c18dea05951482e263982911fc7410b1ffd1dadd3440"}, + {file = "pytokens-0.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a58d057208cb9075c144950d789511220b07636dd2e4708d5645d24de666bdc"}, + {file = "pytokens-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b49750419d300e2b5a3813cf229d4e5a4c728dae470bcc89867a9ad6f25a722d"}, + {file = "pytokens-0.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d9907d61f15bf7261d7e775bd5d7ee4d2930e04424bab1972591918497623a16"}, + {file = "pytokens-0.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:ee44d0f85b803321710f9239f335aafe16553b39106384cef8e6de40cb4ef2f6"}, + {file = "pytokens-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:140709331e846b728475786df8aeb27d24f48cbcf7bcd449f8de75cae7a45083"}, + {file = "pytokens-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d6c4268598f762bc8e91f5dbf2ab2f61f7b95bdc07953b602db879b3c8c18e1"}, + {file = "pytokens-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:24afde1f53d95348b5a0eb19488661147285ca4dd7ed752bbc3e1c6242a304d1"}, + {file = "pytokens-0.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5ad948d085ed6c16413eb5fec6b3e02fa00dc29a2534f088d3302c47eb59adf9"}, + {file = "pytokens-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:3f901fe783e06e48e8cbdc82d631fca8f118333798193e026a50ce1b3757ea68"}, + {file = "pytokens-0.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8bdb9d0ce90cbf99c525e75a2fa415144fd570a1ba987380190e8b786bc6ef9b"}, + {file = "pytokens-0.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5502408cab1cb18e128570f8d598981c68a50d0cbd7c61312a90507cd3a1276f"}, + {file = "pytokens-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:29d1d8fb1030af4d231789959f21821ab6325e463f0503a61d204343c9b355d1"}, + {file = "pytokens-0.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:970b08dd6b86058b6dc07efe9e98414f5102974716232d10f32ff39701e841c4"}, + {file = "pytokens-0.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:9bd7d7f544d362576be74f9d5901a22f317efc20046efe2034dced238cbbfe78"}, + {file = "pytokens-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4a14d5f5fc78ce85e426aa159489e2d5961acf0e47575e08f35584009178e321"}, + {file = "pytokens-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f50fd18543be72da51dd505e2ed20d2228c74e0464e4262e4899797803d7fa"}, + {file = "pytokens-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dc74c035f9bfca0255c1af77ddd2d6ae8419012805453e4b0e7513e17904545d"}, + {file = "pytokens-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f66a6bbe741bd431f6d741e617e0f39ec7257ca1f89089593479347cc4d13324"}, + {file = "pytokens-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:b35d7e5ad269804f6697727702da3c517bb8a5228afa450ab0fa787732055fc9"}, + {file = "pytokens-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:8fcb9ba3709ff77e77f1c7022ff11d13553f3c30299a9fe246a166903e9091eb"}, + {file = "pytokens-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:79fc6b8699564e1f9b521582c35435f1bd32dd06822322ec44afdeba666d8cb3"}, + {file = "pytokens-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d31b97b3de0f61571a124a00ffe9a81fb9939146c122c11060725bd5aea79975"}, + {file = "pytokens-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:967cf6e3fd4adf7de8fc73cd3043754ae79c36475c1c11d514fc72cf5490094a"}, + {file = "pytokens-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:584c80c24b078eec1e227079d56dc22ff755e0ba8654d8383b2c549107528918"}, + {file = "pytokens-0.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:da5baeaf7116dced9c6bb76dc31ba04a2dc3695f3d9f74741d7910122b456edc"}, + {file = "pytokens-0.4.1-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:11edda0942da80ff58c4408407616a310adecae1ddd22eef8c692fe266fa5009"}, + {file = "pytokens-0.4.1-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0fc71786e629cef478cbf29d7ea1923299181d0699dbe7c3c0f4a583811d9fc1"}, + {file = "pytokens-0.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:dcafc12c30dbaf1e2af0490978352e0c4041a7cde31f4f81435c2a5e8b9cabb6"}, + {file = "pytokens-0.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:42f144f3aafa5d92bad964d471a581651e28b24434d184871bd02e3a0d956037"}, + {file = "pytokens-0.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:34bcc734bd2f2d5fe3b34e7b3c0116bfb2397f2d9666139988e7a3eb5f7400e3"}, + {file = "pytokens-0.4.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:941d4343bf27b605e9213b26bfa1c4bf197c9c599a9627eb7305b0defcfe40c1"}, + {file = "pytokens-0.4.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3ad72b851e781478366288743198101e5eb34a414f1d5627cdd585ca3b25f1db"}, + {file = "pytokens-0.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:682fa37ff4d8e95f7df6fe6fe6a431e8ed8e788023c6bcc0f0880a12eab80ad1"}, + {file = "pytokens-0.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:30f51edd9bb7f85c748979384165601d028b84f7bd13fe14d3e065304093916a"}, + {file = "pytokens-0.4.1-py3-none-any.whl", hash = "sha256:26cef14744a8385f35d0e095dc8b3a7583f6c953c2e3d269c7f82484bf5ad2de"}, + {file = "pytokens-0.4.1.tar.gz", hash = "sha256:292052fe80923aae2260c073f822ceba21f3872ced9a68bb7953b348e561179a"}, ] +[package.extras] +dev = ["black", "build", "mypy", "pytest", "pytest-cov", "setuptools", "tox", "twine", "wheel"] + [[package]] name = "pyyaml" version = "6.0.2" @@ -1601,19 +2331,19 @@ files = [ [[package]] name = "requests" -version = "2.32.3" +version = "2.32.5" description = "Python HTTP for Humans." optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["main"] files = [ - {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, - {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, + {file = "requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6"}, + {file = "requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf"}, ] [package.dependencies] certifi = ">=2017.4.17" -charset-normalizer = ">=2,<4" +charset_normalizer = ">=2,<4" idna = ">=2.5,<4" urllib3 = ">=1.21.1,<3" @@ -1621,6 +2351,25 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] +[[package]] +name = "requests-oauthlib" +version = "2.0.0" +description = "OAuthlib authentication support for Requests." +optional = false +python-versions = ">=3.4" +groups = ["main"] +files = [ + {file = "requests-oauthlib-2.0.0.tar.gz", hash = "sha256:b3dffaebd884d8cd778494369603a9e7b58d29111bf6b41bdc2dcd87203af4e9"}, + {file = "requests_oauthlib-2.0.0-py2.py3-none-any.whl", hash = "sha256:7dd8a5c40426b779b0868c404bdef9768deccf22749cde15852df527e6269b36"}, +] + +[package.dependencies] +oauthlib = ">=3.0.0" +requests = ">=2.0.0" + +[package.extras] +rsa = ["oauthlib[signedtoken] (>=3.0.0)"] + [[package]] name = "rich" version = "13.9.4" @@ -1670,19 +2419,19 @@ files = [ [[package]] name = "setuptools" -version = "75.8.0" +version = "78.1.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "setuptools-75.8.0-py3-none-any.whl", hash = "sha256:e3982f444617239225d675215d51f6ba05f845d4eec313da4418fdbb56fb27e3"}, - {file = "setuptools-75.8.0.tar.gz", hash = "sha256:c5afc8f407c626b8313a86e10311dd3f661c6cd9c09d4bf8c15c0e11f9f2b0e6"}, + {file = "setuptools-78.1.1-py3-none-any.whl", hash = "sha256:c3a9c4211ff4c309edb8b8c4f1cbfa7ae324c4ba9f91ff254e3d305b9fd54561"}, + {file = "setuptools-78.1.1.tar.gz", hash = "sha256:fcc17fd9cd898242f6b4adfaca46137a9edef687f43e6f78469692a5e70d851d"}, ] [package.extras] check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\"", "ruff (>=0.8.0) ; sys_platform != \"cygwin\""] -core = ["importlib_metadata (>=6) ; python_version < \"3.10\"", "jaraco.collections", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1) ; python_version < \"3.11\"", "wheel (>=0.43.0)"] +core = ["importlib_metadata (>=6) ; python_version < \"3.10\"", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1) ; python_version < \"3.11\"", "wheel (>=0.43.0)"] cover = ["pytest-cov"] doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] enabler = ["pytest-enabler (>=2.2)"] @@ -1735,6 +2484,7 @@ description = "Provider of IANA time zone data" optional = false python-versions = ">=2" groups = ["main"] +markers = "sys_platform == \"win32\" or sys_platform == \"emscripten\"" files = [ {file = "tzdata-2025.1-py2.py3-none-any.whl", hash = "sha256:7e127113816800496f027041c570f50bcd464a020098a3b6b199517772303639"}, {file = "tzdata-2025.1.tar.gz", hash = "sha256:24894909e88cdb28bd1636c6887801df64cb485bd593f2fd83ef29075a81d694"}, @@ -1742,41 +2492,150 @@ files = [ [[package]] name = "urllib3" -version = "2.3.0" +version = "2.6.3" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, - {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, + {file = "urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"}, + {file = "urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed"}, ] [package.extras] -brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] +brotli = ["brotli (>=1.2.0) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=1.2.0.0) ; platform_python_implementation != \"CPython\""] h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] +zstd = ["backports-zstd (>=1.0.0) ; python_version < \"3.14\""] [[package]] name = "werkzeug" -version = "3.1.3" +version = "3.1.6" description = "The comprehensive WSGI web application library." optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "werkzeug-3.1.3-py3-none-any.whl", hash = "sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e"}, - {file = "werkzeug-3.1.3.tar.gz", hash = "sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746"}, + {file = "werkzeug-3.1.6-py3-none-any.whl", hash = "sha256:7ddf3357bb9564e407607f988f683d72038551200c704012bb9a4c523d42f131"}, + {file = "werkzeug-3.1.6.tar.gz", hash = "sha256:210c6bede5a420a913956b4791a7f4d6843a43b6fcee4dfa08a65e93007d0d25"}, ] [package.dependencies] -MarkupSafe = ">=2.1.1" +markupsafe = ">=2.1.1" [package.extras] watchdog = ["watchdog (>=2.3)"] +[[package]] +name = "wrapt" +version = "1.17.2" +description = "Module for decorators, wrappers and monkey patching." +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "wrapt-1.17.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3d57c572081fed831ad2d26fd430d565b76aa277ed1d30ff4d40670b1c0dd984"}, + {file = "wrapt-1.17.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b5e251054542ae57ac7f3fba5d10bfff615b6c2fb09abeb37d2f1463f841ae22"}, + {file = "wrapt-1.17.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:80dd7db6a7cb57ffbc279c4394246414ec99537ae81ffd702443335a61dbf3a7"}, + {file = "wrapt-1.17.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a6e821770cf99cc586d33833b2ff32faebdbe886bd6322395606cf55153246c"}, + {file = "wrapt-1.17.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b60fb58b90c6d63779cb0c0c54eeb38941bae3ecf7a73c764c52c88c2dcb9d72"}, + {file = "wrapt-1.17.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b870b5df5b71d8c3359d21be8f0d6c485fa0ebdb6477dda51a1ea54a9b558061"}, + {file = "wrapt-1.17.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4011d137b9955791f9084749cba9a367c68d50ab8d11d64c50ba1688c9b457f2"}, + {file = "wrapt-1.17.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:1473400e5b2733e58b396a04eb7f35f541e1fb976d0c0724d0223dd607e0f74c"}, + {file = "wrapt-1.17.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3cedbfa9c940fdad3e6e941db7138e26ce8aad38ab5fe9dcfadfed9db7a54e62"}, + {file = "wrapt-1.17.2-cp310-cp310-win32.whl", hash = "sha256:582530701bff1dec6779efa00c516496968edd851fba224fbd86e46cc6b73563"}, + {file = "wrapt-1.17.2-cp310-cp310-win_amd64.whl", hash = "sha256:58705da316756681ad3c9c73fd15499aa4d8c69f9fd38dc8a35e06c12468582f"}, + {file = "wrapt-1.17.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ff04ef6eec3eee8a5efef2401495967a916feaa353643defcc03fc74fe213b58"}, + {file = "wrapt-1.17.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4db983e7bca53819efdbd64590ee96c9213894272c776966ca6306b73e4affda"}, + {file = "wrapt-1.17.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9abc77a4ce4c6f2a3168ff34b1da9b0f311a8f1cfd694ec96b0603dff1c79438"}, + {file = "wrapt-1.17.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b929ac182f5ace000d459c59c2c9c33047e20e935f8e39371fa6e3b85d56f4a"}, + {file = "wrapt-1.17.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f09b286faeff3c750a879d336fb6d8713206fc97af3adc14def0cdd349df6000"}, + {file = "wrapt-1.17.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7ed2d9d039bd41e889f6fb9364554052ca21ce823580f6a07c4ec245c1f5d6"}, + {file = "wrapt-1.17.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:129a150f5c445165ff941fc02ee27df65940fcb8a22a61828b1853c98763a64b"}, + {file = "wrapt-1.17.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1fb5699e4464afe5c7e65fa51d4f99e0b2eadcc176e4aa33600a3df7801d6662"}, + {file = "wrapt-1.17.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9a2bce789a5ea90e51a02dfcc39e31b7f1e662bc3317979aa7e5538e3a034f72"}, + {file = "wrapt-1.17.2-cp311-cp311-win32.whl", hash = "sha256:4afd5814270fdf6380616b321fd31435a462019d834f83c8611a0ce7484c7317"}, + {file = "wrapt-1.17.2-cp311-cp311-win_amd64.whl", hash = "sha256:acc130bc0375999da18e3d19e5a86403667ac0c4042a094fefb7eec8ebac7cf3"}, + {file = "wrapt-1.17.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d5e2439eecc762cd85e7bd37161d4714aa03a33c5ba884e26c81559817ca0925"}, + {file = "wrapt-1.17.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3fc7cb4c1c744f8c05cd5f9438a3caa6ab94ce8344e952d7c45a8ed59dd88392"}, + {file = "wrapt-1.17.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8fdbdb757d5390f7c675e558fd3186d590973244fab0c5fe63d373ade3e99d40"}, + {file = "wrapt-1.17.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bb1d0dbf99411f3d871deb6faa9aabb9d4e744d67dcaaa05399af89d847a91d"}, + {file = "wrapt-1.17.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d18a4865f46b8579d44e4fe1e2bcbc6472ad83d98e22a26c963d46e4c125ef0b"}, + {file = "wrapt-1.17.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc570b5f14a79734437cb7b0500376b6b791153314986074486e0b0fa8d71d98"}, + {file = "wrapt-1.17.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6d9187b01bebc3875bac9b087948a2bccefe464a7d8f627cf6e48b1bbae30f82"}, + {file = "wrapt-1.17.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:9e8659775f1adf02eb1e6f109751268e493c73716ca5761f8acb695e52a756ae"}, + {file = "wrapt-1.17.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e8b2816ebef96d83657b56306152a93909a83f23994f4b30ad4573b00bd11bb9"}, + {file = "wrapt-1.17.2-cp312-cp312-win32.whl", hash = "sha256:468090021f391fe0056ad3e807e3d9034e0fd01adcd3bdfba977b6fdf4213ea9"}, + {file = "wrapt-1.17.2-cp312-cp312-win_amd64.whl", hash = "sha256:ec89ed91f2fa8e3f52ae53cd3cf640d6feff92ba90d62236a81e4e563ac0e991"}, + {file = "wrapt-1.17.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6ed6ffac43aecfe6d86ec5b74b06a5be33d5bb9243d055141e8cabb12aa08125"}, + {file = "wrapt-1.17.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:35621ae4c00e056adb0009f8e86e28eb4a41a4bfa8f9bfa9fca7d343fe94f998"}, + {file = "wrapt-1.17.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a604bf7a053f8362d27eb9fefd2097f82600b856d5abe996d623babd067b1ab5"}, + {file = "wrapt-1.17.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cbabee4f083b6b4cd282f5b817a867cf0b1028c54d445b7ec7cfe6505057cf8"}, + {file = "wrapt-1.17.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49703ce2ddc220df165bd2962f8e03b84c89fee2d65e1c24a7defff6f988f4d6"}, + {file = "wrapt-1.17.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8112e52c5822fc4253f3901b676c55ddf288614dc7011634e2719718eaa187dc"}, + {file = "wrapt-1.17.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9fee687dce376205d9a494e9c121e27183b2a3df18037f89d69bd7b35bcf59e2"}, + {file = "wrapt-1.17.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:18983c537e04d11cf027fbb60a1e8dfd5190e2b60cc27bc0808e653e7b218d1b"}, + {file = "wrapt-1.17.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:703919b1633412ab54bcf920ab388735832fdcb9f9a00ae49387f0fe67dad504"}, + {file = "wrapt-1.17.2-cp313-cp313-win32.whl", hash = "sha256:abbb9e76177c35d4e8568e58650aa6926040d6a9f6f03435b7a522bf1c487f9a"}, + {file = "wrapt-1.17.2-cp313-cp313-win_amd64.whl", hash = "sha256:69606d7bb691b50a4240ce6b22ebb319c1cfb164e5f6569835058196e0f3a845"}, + {file = "wrapt-1.17.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:4a721d3c943dae44f8e243b380cb645a709ba5bd35d3ad27bc2ed947e9c68192"}, + {file = "wrapt-1.17.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:766d8bbefcb9e00c3ac3b000d9acc51f1b399513f44d77dfe0eb026ad7c9a19b"}, + {file = "wrapt-1.17.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e496a8ce2c256da1eb98bd15803a79bee00fc351f5dfb9ea82594a3f058309e0"}, + {file = "wrapt-1.17.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d615e4fe22f4ad3528448c193b218e077656ca9ccb22ce2cb20db730f8d306"}, + {file = "wrapt-1.17.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a5aaeff38654462bc4b09023918b7f21790efb807f54c000a39d41d69cf552cb"}, + {file = "wrapt-1.17.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a7d15bbd2bc99e92e39f49a04653062ee6085c0e18b3b7512a4f2fe91f2d681"}, + {file = "wrapt-1.17.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e3890b508a23299083e065f435a492b5435eba6e304a7114d2f919d400888cc6"}, + {file = "wrapt-1.17.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:8c8b293cd65ad716d13d8dd3624e42e5a19cc2a2f1acc74b30c2c13f15cb61a6"}, + {file = "wrapt-1.17.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4c82b8785d98cdd9fed4cac84d765d234ed3251bd6afe34cb7ac523cb93e8b4f"}, + {file = "wrapt-1.17.2-cp313-cp313t-win32.whl", hash = "sha256:13e6afb7fe71fe7485a4550a8844cc9ffbe263c0f1a1eea569bc7091d4898555"}, + {file = "wrapt-1.17.2-cp313-cp313t-win_amd64.whl", hash = "sha256:eaf675418ed6b3b31c7a989fd007fa7c3be66ce14e5c3b27336383604c9da85c"}, + {file = "wrapt-1.17.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5c803c401ea1c1c18de70a06a6f79fcc9c5acfc79133e9869e730ad7f8ad8ef9"}, + {file = "wrapt-1.17.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f917c1180fdb8623c2b75a99192f4025e412597c50b2ac870f156de8fb101119"}, + {file = "wrapt-1.17.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ecc840861360ba9d176d413a5489b9a0aff6d6303d7e733e2c4623cfa26904a6"}, + {file = "wrapt-1.17.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb87745b2e6dc56361bfde481d5a378dc314b252a98d7dd19a651a3fa58f24a9"}, + {file = "wrapt-1.17.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58455b79ec2661c3600e65c0a716955adc2410f7383755d537584b0de41b1d8a"}, + {file = "wrapt-1.17.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4e42a40a5e164cbfdb7b386c966a588b1047558a990981ace551ed7e12ca9c2"}, + {file = "wrapt-1.17.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:91bd7d1773e64019f9288b7a5101f3ae50d3d8e6b1de7edee9c2ccc1d32f0c0a"}, + {file = "wrapt-1.17.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:bb90fb8bda722a1b9d48ac1e6c38f923ea757b3baf8ebd0c82e09c5c1a0e7a04"}, + {file = "wrapt-1.17.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:08e7ce672e35efa54c5024936e559469436f8b8096253404faeb54d2a878416f"}, + {file = "wrapt-1.17.2-cp38-cp38-win32.whl", hash = "sha256:410a92fefd2e0e10d26210e1dfb4a876ddaf8439ef60d6434f21ef8d87efc5b7"}, + {file = "wrapt-1.17.2-cp38-cp38-win_amd64.whl", hash = "sha256:95c658736ec15602da0ed73f312d410117723914a5c91a14ee4cdd72f1d790b3"}, + {file = "wrapt-1.17.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:99039fa9e6306880572915728d7f6c24a86ec57b0a83f6b2491e1d8ab0235b9a"}, + {file = "wrapt-1.17.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2696993ee1eebd20b8e4ee4356483c4cb696066ddc24bd70bcbb80fa56ff9061"}, + {file = "wrapt-1.17.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:612dff5db80beef9e649c6d803a8d50c409082f1fedc9dbcdfde2983b2025b82"}, + {file = "wrapt-1.17.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62c2caa1585c82b3f7a7ab56afef7b3602021d6da34fbc1cf234ff139fed3cd9"}, + {file = "wrapt-1.17.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c958bcfd59bacc2d0249dcfe575e71da54f9dcf4a8bdf89c4cb9a68a1170d73f"}, + {file = "wrapt-1.17.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc78a84e2dfbc27afe4b2bd7c80c8db9bca75cc5b85df52bfe634596a1da846b"}, + {file = "wrapt-1.17.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ba0f0eb61ef00ea10e00eb53a9129501f52385c44853dbd6c4ad3f403603083f"}, + {file = "wrapt-1.17.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1e1fe0e6ab7775fd842bc39e86f6dcfc4507ab0ffe206093e76d61cde37225c8"}, + {file = "wrapt-1.17.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c86563182421896d73858e08e1db93afdd2b947a70064b813d515d66549e15f9"}, + {file = "wrapt-1.17.2-cp39-cp39-win32.whl", hash = "sha256:f393cda562f79828f38a819f4788641ac7c4085f30f1ce1a68672baa686482bb"}, + {file = "wrapt-1.17.2-cp39-cp39-win_amd64.whl", hash = "sha256:36ccae62f64235cf8ddb682073a60519426fdd4725524ae38874adf72b5f2aeb"}, + {file = "wrapt-1.17.2-py3-none-any.whl", hash = "sha256:b18f2d1533a71f069c7f82d524a52599053d4c7166e9dd374ae2136b7f40f7c8"}, + {file = "wrapt-1.17.2.tar.gz", hash = "sha256:41388e9d4d1522446fe79d3213196bd9e3b301a336965b9e27ca2788ebd122f3"}, +] + +[[package]] +name = "zipp" +version = "3.21.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931"}, + {file = "zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4"}, +] + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["big-O", "importlib-resources ; python_version < \"3.9\"", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] +type = ["pytest-mypy"] + [metadata] lock-version = "2.1" python-versions = ">=3.12" -content-hash = "5836f9097a4ed5140add03c4fa9c8401c6d5fe20406b5ef08a0eb69839e5f86d" +content-hash = "658f9adae84e4c173735ef4b4a9aeee890662c81cb1dd532a9c70a7b6208b10b" diff --git a/api/pyproject.toml b/api/pyproject.toml index 0bad784d..f086136a 100644 --- a/api/pyproject.toml +++ b/api/pyproject.toml @@ -9,20 +9,24 @@ license = {text = "MIT"} readme = "README.md" requires-python = ">=3.12" dependencies = [ - "azure-cosmosdb-table (>=1.0.6,<2.0.0)", - "numpy (>=2.2.3,<3.0.0)", - "kiwisolver (>=1.4.8,<2.0.0)", - "contourpy (>=1.3.1,<2.0.0)", - "pillow (>=11.1.0,<12.0.0)", - "cffi (>=1.17.1,<2.0.0)", - "openpyxl (>=3.1.5,<4.0.0)", - "pandas (>=2.2.3,<3.0.0)", - "flask (>=3.1.0,<4.0.0)", - "gunicorn (>=23.0.0,<24.0.0)", - "matplotlib (>=3.10.0,<4.0.0)", - "cachetools (>=5.5.2,<6.0.0)", - "pyjwt (>=2.10.1,<3.0.0)", - "azure-storage-blob (>=12.24.1,<13.0.0)" + "azure-cosmosdb-table~=1.0.6", + "numpy~=2.4.2", + "kiwisolver~=1.4.9", + "contourpy~=1.3.3", + "pillow~=12.1.1", + "cffi~=2.0.0", + "openpyxl~=3.1.5", + "pandas~=3.0.1", + "flask~=3.1.3", + "gunicorn~=25.1.0", + "matplotlib~=3.10.8", + "cachetools~=7.0.1", + "pyjwt~=2.11.0", + "azure-storage-blob~=12.28.0", + "opentelemetry-api~=1.39", + "opentelemetry-sdk~=1.39", + "opentelemetry-instrumentation-flask~=0.60b0", + "azure-monitor-opentelemetry~=1.8.6" ] @@ -37,7 +41,7 @@ package-mode = false pytest = "^8.3.4" bandit = "^1.8.3" ruff = "^0.9.7" -black = "^25.1.0" +black = "^26.3.1" coverage = "^7.6.12" [tool.ruff] @@ -46,7 +50,7 @@ src = ["src"] target-version = "py310" line-length = 120 # This is the prefered line-length. ruff will _try_ to make this -select = [ +lint.select = [ "E", # pycodestyle errors "W", # pycodestyle warnings "F", # pyflakes @@ -58,7 +62,7 @@ select = [ "RUF", # ruff specific rules ] -ignore = [ +lint.ignore = [ "W191", # conflict with ruff formatter "B008", # do not perform function calls in argument defaults "E501", # line too long (ruff formater is doing the best it can. Fix them yourself if you dont like the line length) diff --git a/api/src/app.py b/api/src/app.py index 6f791146..8ae41497 100644 --- a/api/src/app.py +++ b/api/src/app.py @@ -1,82 +1,74 @@ -import traceback - -from flask import Flask, Response, request, send_file +from flask import Flask, g, request, send_file +import util.logging as logging from calculators.bridge import SIZE_STEPS from config import Config -from controllers.combination import bridge_from_combination -from controllers.optimal_bridge import bridgeRequestHandler -from controllers.optimizer import optimizer_request_handler -from controllers.products import products_get -from controllers.report import create_report -from util.authentication import authorize -from util.sync_share_point_az import sync_all +from use_cases.bridge_from_combination import bridge_from_combination +from use_cases.calculate_optimal_bridge import calculate_optimal_bridge +from use_cases.create_report import create_report +from use_cases.get_products import get_products +from use_cases.run_optimizer import run_optimizer +from use_cases.synchronize_with_sharepoint import synchronize_with_sharepoint +from util.authentication import authenticate_request +from util.exception_handling import handle_exceptions +from util.utils import convert_keys_camel_to_underscore, convert_keys_underscore_to_camel def init_api(): flask_app = Flask(__name__) flask_app.config.from_object(Config) + logging.init_logging(flask_app) + flask_app.before_request(authenticate_request) return flask_app app = init_api() +@app.route("/api/me", methods=["GET"]) +@handle_exceptions +def me(): + return {"name": g.user.name, "email": g.user.email, "oid": g.user.oid} + + @app.route("/api/products", methods=["GET"]) -@authorize +@handle_exceptions def products(): - return products_get() + return get_products() @app.route("/api/report", methods=["POST"]) -@authorize +@handle_exceptions def report(): return send_file(create_report(request.json), mimetype="application/pdf") @app.route("/api/combination", methods=["POST"]) -@authorize +@handle_exceptions def combination(): return bridge_from_combination(request.json) @app.route("/api/bridge", methods=["POST"]) -@authorize +@handle_exceptions def bridge(): - return bridgeRequestHandler(request.json.get("option"), int(request.json.get("value"))) + return calculate_optimal_bridge(request.json.get("option"), request.json.get("value")) @app.route("/api/sync", methods=["POST"]) -@authorize +@handle_exceptions def sync_sharepoint(): - try: - sync_all() - except Exception as error: - traceback.print_exc() - return Response(str(error), 500) - return "ok" + return synchronize_with_sharepoint() @app.route("/api/fractions", methods=["GET"]) -@authorize +@handle_exceptions def size_fractions(): return {"size_fractions": SIZE_STEPS} @app.route("/api/optimizer", methods=["POST"]) -@authorize -def main(): - value = request.json.get("value") - name = request.json.get("name") - products = request.json.get("products") - density = request.json.get("density") - volume = request.json.get("volume") - option = request.json.get("option") - iterations = request.json.get("iterations") - max_products = request.json.get("maxProducts") - particle_range = request.json.get("particleRange") - weights = request.json.get("weights") - - return optimizer_request_handler( - value, name, products, density, volume, option, iterations, max_products, particle_range, weights - ) +@handle_exceptions +def optimizer(): + response_dict = run_optimizer(convert_keys_camel_to_underscore(request.json)) + return convert_keys_underscore_to_camel(response_dict) diff --git a/api/src/controllers/__init__.py b/api/src/calculators/__init__.py similarity index 100% rename from api/src/controllers/__init__.py rename to api/src/calculators/__init__.py diff --git a/api/src/calculators/bridge.py b/api/src/calculators/bridge.py index 758b5bce..7ab67bdc 100644 --- a/api/src/calculators/bridge.py +++ b/api/src/calculators/bridge.py @@ -4,10 +4,11 @@ from classes.product import Product from util.enums import BridgeOption +from util.exceptions import ValidationException @cached(cache=LFUCache(2048)) -def theoretical_bridge(mode: str, value: int): +def theoretical_bridge(mode: str, value: int) -> list[float]: bridge_list = [] d_value = 50 bridge_input = value @@ -19,7 +20,7 @@ def theoretical_bridge(mode: str, value: int): elif mode in (BridgeOption.AVERAGE_PORESIZE, BridgeOption.CERAMIC_DISCS): pass else: - raise ValueError(f"Invalid bridge mode string '{mode}'") + raise ValidationException(f"Invalid bridge mode string '{mode}'") result = 100 * (sqrt(bridge_input) / d_value) @@ -32,7 +33,7 @@ def theoretical_bridge(mode: str, value: int): return bridge_list -def calculate_blend_cumulative(product_list: list[Product]): +def calculate_blend_cumulative(product_list: list[Product]) -> list[float]: cumulative_curve: list[float] = [0.0 for _ in SIZE_STEPS] for product in product_list: diff --git a/api/src/calculators/fraction_interpolator.py b/api/src/calculators/fraction_interpolator.py deleted file mode 100644 index 7642fffb..00000000 --- a/api/src/calculators/fraction_interpolator.py +++ /dev/null @@ -1,63 +0,0 @@ -import csv -from copy import copy - -from numpy import log - -from calculators.bridge import SIZE_STEPS - - -def lookup_smaller(table: dict, value: float): - n = [i for i in table.keys() if i <= value] - return max(n) - - -def lookup_bigger(table: dict, value: float): - n = [i for i in table.keys() if i >= value] - return min(n) - - -def fraction_interpolator(x: list[float], y: list[float], z: list[float]) -> list[float]: - table_dict = dict(zip(x, y, strict=False)) - max_x = max(x) - - z_table = {} - for _z in z: - if _z > max_x: - break - smaller_x = lookup_smaller(table_dict, _z) - bigger_x = lookup_bigger(table_dict, _z) - z_table[_z] = {"x1": smaller_x, "x2": bigger_x, "y1": table_dict[smaller_x], "y2": table_dict[bigger_x]} - - for zz, values in z_table.items(): - x1 = values["x1"] - x2 = values["x2"] - y1 = values["y1"] - y2 = values["y2"] - - values["j"] = (y2 - y1) / (log(x2) - log(x1)) * (log(zz) - log(x1)) + y1 - return [round(v["j"], 3) for v in z_table.values()] - - -def from_csv_to_csv(): - with open("test_data/interpolate_input.csv") as csvfile: - reader = csv.DictReader(csvfile) - fields_copy = copy(reader.fieldnames) - fields_copy.pop(0) - products = {name: [] for name in fields_copy} - a_x = [] - for line in reader: - a_x.append(float(line["Size"])) - for n in products: - products[n].append(float(line[n])) - - for name in products: - b_y = fraction_interpolator(x=a_x, y=products[name], z=SIZE_STEPS) - with open(f"test_data/{name}.csv", "w+") as newcsvfile: - writer = csv.DictWriter(newcsvfile, fieldnames=["Size", "Cumulative"]) - writer.writeheader() - for step, interpol_value in zip(SIZE_STEPS, b_y, strict=False): - writer.writerow({"Size": step, "Cumulative": interpol_value}) - - -if __name__ == "__main__": - from_csv_to_csv() diff --git a/api/src/calculators/optimizer.py b/api/src/calculators/optimizer.py index c824058d..742f453d 100644 --- a/api/src/calculators/optimizer.py +++ b/api/src/calculators/optimizer.py @@ -1,16 +1,48 @@ # ruff: noqa: S311 -import pickle # nosec import random -from datetime import datetime +from dataclasses import dataclass, field +from datetime import datetime, timedelta import numpy as np from cachetools import LFUCache, cached +from cachetools.keys import hashkey from calculators.bridge import SIZE_STEPS, calculate_blend_cumulative from classes.product import Product +from use_cases.get_products import ProductDTO +from util.exceptions import InternalErrorException, ValidationException +def hash_combination(self, combination: dict[str, float]): + return hashkey(frozenset(combination.items())) + + +@dataclass +class OptimizerWeights: + bridge: int + mass: int + products: int + + def __post_init__(self): + for i in self.__dict__.values(): + if not 0 <= i <= 10: + raise ValidationException("Weighting values must be between 1 and 10") + + +@dataclass +class OptimizationResult: + combination: dict[str, float] + cumulative_bridge: list[float] + curve: list[float] + execution_time: timedelta + iterations: int + score: float + bridge_score: float + + +@dataclass class Optimizer: + # constants POPULATION_SIZE = 20 NUMBER_OF_CHILDREN = 18 # must be a multiple of 2 NUMBER_OF_PARENTS = 2 @@ -26,33 +58,29 @@ class Optimizer: MASS_IMPORTANCE = 10 NUMBER_OF_PRODUCTS_IMPORTANCE = 40 - def __init__( - self, - bridge: list[float], - products: list[dict] | None = None, - density_goal: int = 350, - volume: int = 10, - max_iterations: int = 500, - max_products: int = 999, - particle_range=None, - weights: dict | None = None, - ): - self.products = products - self.bridge = bridge - self.mass_goal = density_goal * volume - self.density_goal = density_goal - self.volume = volume - self.max_iterations = max_iterations - self.max_products = max_products - if particle_range is None: - particle_range = [1.0, 100] - if particle_range[1] <= 0: - particle_range[1] = 10000 - self.particle_range = particle_range - self.weights = weights if weights else {"bridge": 10, "mass": 1, "products": 1} - self.sum_weights = sum(self.weights.values()) - - def optimize(self): + # parameters + bridge: list[float] + products: list[ProductDTO] + density_goal: float = 350 + volume: float = 10 + max_iterations: int = 500 + max_products: int = 999 + particle_range: tuple[float, float] = (1.0, 100) + weights: OptimizerWeights = field(default_factory=lambda: OptimizerWeights(bridge=5, mass=5, products=5)) + + def __post_init__(self): + if self.particle_range[1] <= 0: + self.particle_range = (self.particle_range[0], 10000) + + @property + def mass_goal(self): + return self.density_goal * self.volume + + @property + def sum_weights(self): + return self.weights.bridge + self.weights.mass + self.weights.products + + def optimize(self) -> OptimizationResult: start = datetime.now() max_initial_density = self.density_goal // min(self.max_products, len(self.products)) @@ -66,25 +94,24 @@ def optimize(self): children = self.execute_mutation(children) population = parents + children score, fittest_combo, experimental_bridge = self.optimal(population) - # for i, _ in enumerate(products): - # combination_progress[i].append(list(fittest_combo.values())[i]) score_progress.append(score) bridge_score = self.bridge_score(experimental_bridge) # standard deviaton - return { - "combination": {k: v for k, v in fittest_combo.items() if v > 0}, - "cumulative_bridge": experimental_bridge, - "curve": score_progress, - "execution_time": (datetime.now() - start), - "iterations": iterations, - "score": score, - "bridge_score": bridge_score, - } + + return OptimizationResult( + combination={k: v for k, v in fittest_combo.items() if v > 0}, + cumulative_bridge=experimental_bridge, + curve=score_progress, + execution_time=(datetime.now() - start), + iterations=iterations, + score=score, + bridge_score=bridge_score, + ) def calculate_performance(self, experimental_bridge: list, products_result: list[Product]) -> dict: bridge_fitness = 100 - self.bridge_score(experimental_bridge) mass_score = 100 - self.mass_score(products_result, squash=False) - products_score = 100 - (self.n_products_score(products_result, squash=False)) + products_score = 100 - self.n_products_score(products_result, squash=False) return {"bridge": bridge_fitness, "mass": mass_score, "products": products_score} @@ -93,10 +120,10 @@ def initialize_population(self, max_initial_density): children = [] if self.max_products < len(self.products): - id_list = [p["id"] for p in self.products] + id_list = [p.id for p in self.products] for _ in range(self.POPULATION_SIZE): - combo_dict = {id: 0 for id in id_list} + combo_dict = dict.fromkeys(id_list, 0) used_id_list = [] for _ in range(self.max_products): @@ -106,7 +133,7 @@ def initialize_population(self, max_initial_density): used_id_list.append(id) for id in used_id_list: - combo_dict[id] = round(random.uniform(0, max_initial_density), 2) + combo_dict[id] = int(round(random.uniform(0, max_initial_density), 2)) population.append(combo_dict) @@ -114,7 +141,7 @@ def initialize_population(self, max_initial_density): for _i in range(self.POPULATION_SIZE): combo_dict = {} for j in range(len(self.products)): - combo_dict[self.products[j]["id"]] = round(random.uniform(0, max_initial_density), 2) + combo_dict[self.products[j].id] = round(random.uniform(0, max_initial_density), 2) population.append(combo_dict) for _i in range(self.NUMBER_OF_CHILDREN): @@ -127,7 +154,7 @@ def select_parents(self, population): fit_dict = {} for combination in population: - score, _ = self.fitness_score(pickle.dumps(combination)) + score, _ = self.fitness_score(combination) fitness.append(score) fit_dict[score] = combination @@ -139,7 +166,7 @@ def select_parents(self, population): def bridge_score(self, experimental_bridge): if len(self.bridge) != len(experimental_bridge): - raise ValueError("The experimental bridge has a different size than the theoretical") + raise InternalErrorException("The experimental bridge has a different size than the theoretical") diff_list = [] i = 0 for theo, blend in zip(self.bridge, experimental_bridge, strict=False): @@ -149,38 +176,38 @@ def bridge_score(self, experimental_bridge): _mean = np.mean(diff_list) score = np.sqrt(_mean) - return score - - @cached(cache=LFUCache(8192)) - def fitness_score(self, pickled_combination: bytes): - combination = pickle.loads(pickled_combination) # noqa: S301 + return float(score) + @cached(cache=LFUCache(8192), key=hash_combination) + def fitness_score(self, combination: dict[str, float]): products: list[Product] = [] for p in self.products: - if combination[p["id"]] > 0: + if combination[p.id] > 0: + if p.cumulative is None: + raise InternalErrorException(f"Product {p.id} does not have cumulative distribution data") products.append( Product( - product_id=p["id"], - share=combination[p["id"]] / sum(combination.values()), - cumulative=p["cumulative"], - sacks=combination[p["id"]], - mass=(combination[p["id"]] * self.volume), + product_id=p.id, + share=combination[p.id] / sum(combination.values()), + cumulative=p.cumulative, + sacks=combination[p.id], + mass=(combination[p.id] * self.volume), ) ) experimental_bridge = calculate_blend_cumulative(products) - _bridge_score = self.bridge_score(experimental_bridge) * (self.weights["bridge"] / self.sum_weights) - mass_score = self.mass_score(products) * (self.weights["mass"] / self.sum_weights) - number_of_products_score = self.n_products_score(products) * (self.weights["products"] / self.sum_weights) + _bridge_score = self.bridge_score(experimental_bridge) * (self.weights.bridge / self.sum_weights) + mass_score = self.mass_score(products) * (self.weights.mass / self.sum_weights) + number_of_products_score = self.n_products_score(products) * (self.weights.products / self.sum_weights) return _bridge_score + mass_score + number_of_products_score, experimental_bridge def optimal(self, population): results = [] for combination in population: - score, exp_bridge = self.fitness_score(pickle.dumps(combination)) + score, exp_bridge = self.fitness_score(combination) results.append({"score": score, "combination": combination, "bridge": exp_bridge}) - results.sort(key=lambda r: (r["score"])) + results.sort(key=lambda r: r["score"]) return results[0]["score"], results[0]["combination"], results[0]["bridge"] def crossover(self, parents, children): diff --git a/api/src/classes/product.py b/api/src/classes/product.py index c3ab7f59..ef9b386a 100644 --- a/api/src/classes/product.py +++ b/api/src/classes/product.py @@ -1,8 +1,11 @@ +from dataclasses import dataclass + + +@dataclass class Product: - def __init__(self, product_id: str, share: float, cumulative: list[float], name="", sacks: int = 0, mass: int = 0): - self.product_id = product_id - self.share = share - self.cumulative = cumulative - self.name = name - self.sacks = sacks - self.mass = mass + product_id: str + share: float + cumulative: list[float] + name: str = "" + sacks: float = 0.0 + mass: float = 0.0 diff --git a/api/src/classes/user.py b/api/src/classes/user.py index d40629b0..e1004b70 100644 --- a/api/src/classes/user.py +++ b/api/src/classes/user.py @@ -1,5 +1,18 @@ +from dataclasses import dataclass, field + + +@dataclass class User: - def __init__(self, name, oid, roles=None, **kwargs): - self.name = name - self.oid = oid - self.roles = roles if roles else [] + name: str + oid: str + email: str + roles: list[str] = field(default_factory=list) + + @classmethod + def from_jwt(cls, jwt_payload: dict): + return cls( + name=jwt_payload.get("name", ""), + oid=jwt_payload.get("oid", ""), + email=jwt_payload.get("email") or jwt_payload.get("upn") or jwt_payload.get("preferred_username", ""), + roles=jwt_payload.get("roles", []), + ) diff --git a/api/src/config.py b/api/src/config.py index bc731252..39a7bda8 100644 --- a/api/src/config.py +++ b/api/src/config.py @@ -1,4 +1,3 @@ -import ast import os from pathlib import Path @@ -6,17 +5,18 @@ class Config: TABLE_ACCOUNT_NAME = os.getenv("TABLE_ACCOUNT_NAME", "lcmdevstorage") TABLE_KEY = os.getenv("TABLE_KEY") + APPINSIGHTS_CON_STRING = os.getenv("APPINSIGHTS_CON_STRING") BLOB_CONTAINER_NAME = "lcm-file-blobs" - LOAD_TEST_DATA = ast.literal_eval(os.getenv("LOAD_TEST_DATA", "False")) - SYNC_BLOBS_APP_URL = os.getenv( - "SYNC_BLOBS_APP_URL", - "https://prod-42.northeurope.logic.azure.com:443/workflows/9a6068e6cd3a463bab9b722a2f89ca98/triggers/manual/paths/invoke?api-version=2016-10-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=X6L0pW_9CUGarHiYNVd6BeeiWRjZxM3DDtnCjvh5kRw", - ) + SYNC_BLOBS_APP_URL = os.getenv("SYNC_BLOBS_APP_URL") AUTH_SECRET = os.getenv("AUTH_SECRET") - AUTH_JWT_AUDIENCE = os.getenv("AUTH_JWT_AUDIENCE", "api://lost-circulation-material-api") - AUTH_JWK_URL = os.getenv("AUTH_JWK_URL", "https://login.microsoftonline.com/common/discovery/v2.0/keys") - ROUNDING_DECIMALS = 3 - DEFAULT_MAX_ITERATIONS = 100 + AUTH_JWT_AUDIENCES = os.getenv( + "AUTH_JWT_AUDIENCES", "api://lost-circulation-material-api,1dbc1e96-268d-41ad-894a-92a9fb85f954" + ).split(",") + AUTH_JWT_ISSUER = os.getenv("AUTH_JWT_ISSUER") + AUTH_OIDC_WELL_KNOWN = os.getenv( + "AUTH_OIDC_WELL_KNOWN", + "https://login.microsoftonline.com/3aa4a235-b6e2-48d5-9195-7fcf05b459b0/v2.0/.well-known/openid-configuration", + ) HOME_DIR = str(Path(__file__).parent.absolute()) PRODUCT_TABLE_NAME = "products" - named_supplier = ("Baker Hughes", "Halliburton", "Schlumberger") + NAMED_SUPPLIERS: tuple[str, ...] = ("Baker Hughes", "Halliburton", "Schlumberger") diff --git a/api/src/controllers/optimizer.py b/api/src/controllers/optimizer.py deleted file mode 100644 index ebb6b72e..00000000 --- a/api/src/controllers/optimizer.py +++ /dev/null @@ -1,89 +0,0 @@ -from flask import Response - -from calculators.bridge import theoretical_bridge -from calculators.optimizer import Optimizer -from classes.product import Product -from controllers.products import products_get - - -def optimizer_request_handler( - value, - blend_name, - products, - density_goal, - volume, - option="AVERAGE_PORESIZE", - iterations: int = 500, - max_products: int = 999, - particle_range: tuple[float, float] = (1.0, 100), - weights: dict | None = None, -): - int_iterations = int(iterations) - if int_iterations <= 0: - return Response("Number of iterations must be a positiv integer", 400) - - if particle_range[0] >= particle_range[1]: - return Response("Particle size 'from' must be smaller than 'to'", 400) - - if max_products == 0: - max_products = 999 - - if not weights: - weights = {"bridge": 5, "mass": 5, "products": 5} - else: - for i in weights.values(): - if not 0 <= i <= 10: - return Response("Weighting values must be between 1 and 10", 400) - - print(f"Started optimization request with {int_iterations} maximum iterations...") - bridge = theoretical_bridge(option, value) - selected_products = [p for p in products_get().values() if p["id"] in products] - if len(selected_products) < 2: - return Response("Can not run the optimizer with less than two products", 400) - - optimizer = Optimizer( - products=selected_products, - bridge=bridge, - density_goal=density_goal, - volume=volume, - max_iterations=int_iterations, - max_products=max_products, - particle_range=particle_range, - weights=weights, - ) - optimizer_result = optimizer.optimize() - combination = optimizer_result["combination"] - - products_result: list[Product] = [] - for p in selected_products: - if p["id"] in combination.keys(): - products_result.append( - Product( - product_id=p["id"], - share=combination[p["id"]] / sum(combination.values()), - cumulative=p["cumulative"], - sacks=combination[p["id"]], - mass=(combination[p["id"]] * volume), - ) - ) - - return { - "name": blend_name, - "config": {"iterations": optimizer_result["iterations"], "value": value, "mode": option}, - "products": {id: {"id": id, "value": combination[id]} for id in combination}, - "performance": optimizer.calculate_performance( - experimental_bridge=optimizer_result["cumulative_bridge"], - products_result=products_result, - ), - "totalMass": round(sum([p.mass for p in products_result]), 1), - "cumulative": optimizer_result["cumulative_bridge"], - "executionTime": int(optimizer_result["execution_time"].microseconds / 1000), - "fitness": optimizer_result["score"], - "weighting": { - "bridge": weights["bridge"], - "mass": weights["mass"], - "products": weights["products"], - }, - "curve": optimizer_result["curve"], - "bridgeScore": optimizer_result["bridge_score"], - } diff --git a/api/src/controllers/products.py b/api/src/controllers/products.py deleted file mode 100644 index 743abedc..00000000 --- a/api/src/controllers/products.py +++ /dev/null @@ -1,38 +0,0 @@ -from cachetools import TTLCache, cached -from flask import Response - -from config import Config -from util.azure_table import get_service - - -def sort_products(products: dict[str, dict]): - values = list(products.values()) - values.sort(key=lambda p: (p["supplier"], p["id"])) - - return {v["id"]: v for v in values} - - -@cached(cache=TTLCache(maxsize=128, ttl=300)) -def products_get(): - products = get_service().query_entities(Config.PRODUCT_TABLE_NAME) - - products_response = {} - for p in products: - products_response[p.RowKey] = dict(p) - del products_response[p.RowKey]["PartitionKey"] - del products_response[p.RowKey]["RowKey"] - del products_response[p.RowKey]["Timestamp"] - del products_response[p.RowKey]["etag"] - products_response[p.RowKey]["sackSize"] = p.sack_size - cumulative = ( - [float(v) for v in p.get("cumulative").replace("[", "").replace("]", "").split(",")] - if p.get("cumulative") - else None - ) - products_response[p.RowKey]["cumulative"] = cumulative - - if not len(products_response): - return Response("Failed to fetch products from storage", 500) - - sorted_products = sort_products(products_response) - return sorted_products diff --git a/api/src/plots/bridge.py b/api/src/plots/bridge.py index 919f754b..823c6fa0 100644 --- a/api/src/plots/bridge.py +++ b/api/src/plots/bridge.py @@ -6,7 +6,8 @@ from calculators.bridge import SIZE_STEPS, calculate_blend_cumulative, theoretical_bridge from classes.product import Product -from controllers.products import products_get +from use_cases.get_products import retrieve_products +from util.exceptions import InternalErrorException def bridge_plot(products: dict, mode, value) -> str: @@ -23,14 +24,18 @@ def bridge_plot(products: dict, mode, value) -> str: bridgeplot.set_xticks([0.1, 1, 10, 100, 1000]) bridgeplot.xaxis.set_major_formatter(ScalarFormatter()) bridgeplot.plot(SIZE_STEPS, bridge, color="black", label="Ideal") - bridgeplot.axes.set_ylim([0, 100]) - bridgeplot.axes.set_xlim([0.01, 10000]) + if bridgeplot.axes: + bridgeplot.axes.set_ylim((0, 100)) + bridgeplot.axes.set_xlim((0.01, 10000)) products_class = [] - all_products = products_get() + all_products = retrieve_products() for id, values in products.items(): + product_dto = all_products[id] + if product_dto.cumulative is None: + raise InternalErrorException(f"Product {id} does not have cumulative distribution data") products_class.append( - Product(product_id=id, share=(values["percentage"] / 100), cumulative=all_products[id]["cumulative"]) + Product(product_id=id, share=(values["percentage"] / 100), cumulative=product_dto.cumulative) ) bridgeplot.plot(SIZE_STEPS, calculate_blend_cumulative(products_class), color="red", label="Blend") diff --git a/api/src/plots/products_pie.py b/api/src/plots/products_pie.py index 70d9bc05..5389c230 100644 --- a/api/src/plots/products_pie.py +++ b/api/src/plots/products_pie.py @@ -32,7 +32,7 @@ def products_pie(products: dict) -> str: fig, ax = plt.subplots() ax.set_title("Product distribution in blend") - wedges, text, auto_texts = ax.pie( + wedges, *_ = ax.pie( product_values, autopct="%1.1f%%", startangle=90, diff --git a/api/src/tests/optimizer_test.py b/api/src/tests/optimizer_test.py index 37634d14..3b98f6c7 100644 --- a/api/src/tests/optimizer_test.py +++ b/api/src/tests/optimizer_test.py @@ -7,6 +7,7 @@ from calculators.bridge import SIZE_STEPS, theoretical_bridge from calculators.optimizer import Optimizer from config import Config +from use_cases.get_products import ProductDTO from util.enums import BridgeOption @@ -23,15 +24,15 @@ def values_within_deviation(array: list, allowed_deviation: float): product_data = [ - { - "id": "1b", - "co2": 1000, - "cost": 100, - "environmental": "Green", - "sack_size": 25, - "supplier": "Jey", - "title": "1 B", - "cumulative": [ + ProductDTO( + id="1b", + co2=1000, + cost=100, + environmental="Green", + sack_size=25, + supplier="Jey", + title="1 B", + cumulative=[ 0.0, 0.0, 0.0, @@ -134,17 +135,16 @@ def values_within_deviation(array: list, allowed_deviation: float): 100.0, 100.0, ], - "sackSize": 25, - }, - { - "id": "2b", - "co2": 1000, - "cost": 100, - "environmental": "Green", - "sack_size": 25, - "supplier": "Jey", - "title": "2 B", - "cumulative": [ + ), + ProductDTO( + id="2b", + co2=1000, + cost=100, + environmental="Green", + sack_size=25, + supplier="Jey", + title="2 B", + cumulative=[ 0.0, 0.0, 0.0, @@ -247,17 +247,16 @@ def values_within_deviation(array: list, allowed_deviation: float): 100.0, 100.0, ], - "sackSize": 25, - }, - { - "id": "3b", - "co2": 1000, - "cost": 100, - "environmental": "Green", - "sack_size": 25, - "supplier": "Jey", - "title": "3 B", - "cumulative": [ + ), + ProductDTO( + id="3b", + co2=1000, + cost=100, + environmental="Green", + sack_size=25, + supplier="Jey", + title="3 B", + cumulative=[ 0.0, 0.0, 0.0, @@ -360,17 +359,16 @@ def values_within_deviation(array: list, allowed_deviation: float): 98.21, 100.0, ], - "sackSize": 25, - }, - { - "id": "1C", - "co2": 1000, - "cost": 100, - "environmental": "Green", - "sack_size": 25, - "supplier": "Neil", - "title": "1 C", - "cumulative": [ + ), + ProductDTO( + id="1C", + co2=1000, + cost=100, + environmental="Green", + sack_size=25, + supplier="Neil", + title="1 C", + cumulative=[ 0.0, 0.0, 0.0, @@ -473,17 +471,16 @@ def values_within_deviation(array: list, allowed_deviation: float): 100.0, 100.0, ], - "sackSize": 25, - }, - { - "id": "2c", - "co2": 1000, - "cost": 100, - "environmental": "Green", - "sack_size": 25, - "supplier": "Neil", - "title": "2 C", - "cumulative": [ + ), + ProductDTO( + id="2c", + co2=1000, + cost=100, + environmental="Green", + sack_size=25, + supplier="Neil", + title="2 C", + cumulative=[ 0.0, 0.0, 0.0, @@ -586,17 +583,16 @@ def values_within_deviation(array: list, allowed_deviation: float): 100.0, 100.0, ], - "sackSize": 25, - }, - { - "id": "1f", - "co2": 1000, - "cost": 100, - "environmental": "Green", - "sack_size": 25, - "supplier": "Odin", - "title": "1 F", - "cumulative": [ + ), + ProductDTO( + id="1f", + co2=1000, + cost=100, + environmental="Green", + sack_size=25, + supplier="Odin", + title="1 F", + cumulative=[ 0.0, 0.0, 0.0, @@ -699,17 +695,16 @@ def values_within_deviation(array: list, allowed_deviation: float): 100.0, 100.0, ], - "sackSize": 25, - }, - { - "id": "2f", - "co2": 1000, - "cost": 100, - "environmental": "Green", - "sack_size": 25, - "supplier": "Odin", - "title": "2 F", - "cumulative": [ + ), + ProductDTO( + id="2f", + co2=1000, + cost=100, + environmental="Green", + sack_size=25, + supplier="Odin", + title="2 F", + cumulative=[ 0.0, 0.0, 0.0, @@ -812,17 +807,16 @@ def values_within_deviation(array: list, allowed_deviation: float): 100.0, 100.0, ], - "sackSize": 25, - }, - { - "id": "4f", - "co2": 1000, - "cost": 100, - "environmental": "Green", - "sack_size": 25, - "supplier": "Neil", - "title": "4 F", - "cumulative": [ + ), + ProductDTO( + id="4f", + co2=1000, + cost=100, + environmental="Green", + sack_size=25, + supplier="Neil", + title="4 F", + cumulative=[ 0.0, 0.0, 0.0, @@ -925,17 +919,16 @@ def values_within_deviation(array: list, allowed_deviation: float): 100.0, 100.0, ], - "sackSize": 25, - }, - { - "id": "5 f", - "co2": 1000, - "cost": 100, - "environmental": "Green", - "sack_size": 25, - "supplier": "Ferdinan", - "title": "6 F", - "cumulative": [ + ), + ProductDTO( + id="5 f", + co2=1000, + cost=100, + environmental="Green", + sack_size=25, + supplier="Ferdinan", + title="6 F", + cumulative=[ 0.0, 0.0, 0.0, @@ -1038,17 +1031,16 @@ def values_within_deviation(array: list, allowed_deviation: float): 100.0, 100.0, ], - "sackSize": 25, - }, - { - "id": "1g", - "co2": 1000, - "cost": 100, - "environmental": "Green", - "sack_size": 25, - "supplier": "Dixi", - "title": "1 G", - "cumulative": [ + ), + ProductDTO( + id="1g", + co2=1000, + cost=100, + environmental="Green", + sack_size=25, + supplier="Dixi", + title="1 G", + cumulative=[ 0.0, 0.0, 0.0, @@ -1151,17 +1143,16 @@ def values_within_deviation(array: list, allowed_deviation: float): 100.0, 100.0, ], - "sackSize": 25, - }, - { - "id": "2g", - "co2": 1000, - "cost": 100, - "environmental": "Green", - "sack_size": 25, - "supplier": "Dixi", - "title": "2 G", - "cumulative": [ + ), + ProductDTO( + id="2g", + co2=1000, + cost=100, + environmental="Green", + sack_size=25, + supplier="Dixi", + title="2 G", + cumulative=[ 0.0, 0.0, 0.0, @@ -1264,17 +1255,16 @@ def values_within_deviation(array: list, allowed_deviation: float): 100.0, 100.0, ], - "sackSize": 25, - }, - { - "id": "3g", - "co2": 1000, - "cost": 100, - "environmental": "Green", - "sack_size": 25, - "supplier": "Dixi", - "title": "3 Ge", - "cumulative": [ + ), + ProductDTO( + id="3g", + co2=1000, + cost=100, + environmental="Green", + sack_size=25, + supplier="Dixi", + title="3 Ge", + cumulative=[ 0.0, 0.0, 0.0, @@ -1377,17 +1367,16 @@ def values_within_deviation(array: list, allowed_deviation: float): 99.32, 100.0, ], - "sackSize": 25, - }, - { - "id": "1l ", - "co2": 1000, - "cost": 100, - "environmental": "Green", - "sack_size": 25, - "supplier": "Neil", - "title": "1 L", - "cumulative": [ + ), + ProductDTO( + id="1l ", + co2=1000, + cost=100, + environmental="Green", + sack_size=25, + supplier="Neil", + title="1 L", + cumulative=[ 0.0, 0.0, 0.0, @@ -1490,17 +1479,16 @@ def values_within_deviation(array: list, allowed_deviation: float): 100.0, 100.0, ], - "sackSize": 25, - }, - { - "id": "1m", - "co2": 1000, - "cost": 100, - "environmental": "Green", - "sack_size": 25, - "supplier": "Neil", - "title": "1 M", - "cumulative": [ + ), + ProductDTO( + id="1m", + co2=1000, + cost=100, + environmental="Green", + sack_size=25, + supplier="Neil", + title="1 M", + cumulative=[ 0.0, 0.0, 0.0, @@ -1603,17 +1591,16 @@ def values_within_deviation(array: list, allowed_deviation: float): 100.0, 100.0, ], - "sackSize": 25, - }, - { - "id": "3 m", - "co2": 1000, - "cost": 100, - "environmental": "Green", - "sack_size": 25, - "supplier": "Neil", - "title": "3 M", - "cumulative": [ + ), + ProductDTO( + id="3 m", + co2=1000, + cost=100, + environmental="Green", + sack_size=25, + supplier="Neil", + title="3 M", + cumulative=[ 0.0, 0.0, 0.0, @@ -1716,17 +1703,16 @@ def values_within_deviation(array: list, allowed_deviation: float): 100.0, 100.0, ], - "sackSize": 25, - }, - { - "id": "3m", - "co2": 1000, - "cost": 100, - "environmental": "Green", - "sack_size": 25, - "supplier": "Neil", - "title": "3 M", - "cumulative": [ + ), + ProductDTO( + id="3m", + co2=1000, + cost=100, + environmental="Green", + sack_size=25, + supplier="Neil", + title="3 M", + cumulative=[ 0.0, 0.0, 0.0, @@ -1829,17 +1815,16 @@ def values_within_deviation(array: list, allowed_deviation: float): 99.96999999999998, 99.96999999999998, ], - "sackSize": 25, - }, - { - "id": "1o", - "co2": 1000, - "cost": 100, - "environmental": "Green", - "sack_size": 25, - "supplier": "Dixi", - "title": "1 O", - "cumulative": [ + ), + ProductDTO( + id="1o", + co2=1000, + cost=100, + environmental="Green", + sack_size=25, + supplier="Dixi", + title="1 O", + cumulative=[ 0.0, 0.0, 0.0, @@ -1942,17 +1927,16 @@ def values_within_deviation(array: list, allowed_deviation: float): 100.0, 100.0, ], - "sackSize": 25, - }, - { - "id": "2o", - "co2": 1000, - "cost": 100, - "environmental": "Green", - "sack_size": 25, - "supplier": "Dixi", - "title": "2 O", - "cumulative": [ + ), + ProductDTO( + id="2o", + co2=1000, + cost=100, + environmental="Green", + sack_size=25, + supplier="Dixi", + title="2 O", + cumulative=[ 0.0, 0.0, 0.0, @@ -2055,17 +2039,16 @@ def values_within_deviation(array: list, allowed_deviation: float): 100.0, 100.0, ], - "sackSize": 25, - }, - { - "id": "1s", - "co2": 1000, - "cost": 100, - "environmental": "Green", - "sack_size": 25, - "supplier": "Dixi", - "title": "1 S", - "cumulative": [ + ), + ProductDTO( + id="1s", + co2=1000, + cost=100, + environmental="Green", + sack_size=25, + supplier="Dixi", + title="1 S", + cumulative=[ 0.0, 0.0, 0.0, @@ -2168,17 +2151,16 @@ def values_within_deviation(array: list, allowed_deviation: float): 97.91, 100.0, ], - "sackSize": 25, - }, - { - "id": "2s", - "co2": 1000, - "cost": 100, - "environmental": "Green", - "sack_size": 25, - "supplier": "Dixi", - "title": "2S", - "cumulative": [ + ), + ProductDTO( + id="2s", + co2=1000, + cost=100, + environmental="Green", + sack_size=25, + supplier="Dixi", + title="2S", + cumulative=[ 0.0, 0.0, 0.0, @@ -2281,17 +2263,16 @@ def values_within_deviation(array: list, allowed_deviation: float): 100.0, 100.0, ], - "sackSize": 25, - }, - { - "id": "3s", - "co2": 1000, - "cost": 100, - "environmental": "Green", - "sack_size": 25, - "supplier": "Dixi", - "title": "3S", - "cumulative": [ + ), + ProductDTO( + id="3s", + co2=1000, + cost=100, + environmental="Green", + sack_size=25, + supplier="Dixi", + title="3S", + cumulative=[ 0.0, 0.0, 0.0, @@ -2394,17 +2375,16 @@ def values_within_deviation(array: list, allowed_deviation: float): 100.0, 100.0, ], - "sackSize": 25, - }, - { - "id": "4s", - "co2": 1000, - "cost": 100, - "environmental": "Green", - "sack_size": 25, - "supplier": "Dixi", - "title": "4S", - "cumulative": [ + ), + ProductDTO( + id="4s", + co2=1000, + cost=100, + environmental="Green", + sack_size=25, + supplier="Dixi", + title="4S", + cumulative=[ 0.0, 0.0, 0.0, @@ -2507,17 +2487,16 @@ def values_within_deviation(array: list, allowed_deviation: float): 100.0, 100.0, ], - "sackSize": 25, - }, - { - "id": "5s", - "co2": 1000, - "cost": 100, - "environmental": "Green", - "sack_size": 25, - "supplier": "Dixi", - "title": "5S", - "cumulative": [ + ), + ProductDTO( + id="5s", + co2=1000, + cost=100, + environmental="Green", + sack_size=25, + supplier="Dixi", + title="5S", + cumulative=[ 0.0, 0.0, 0.0, @@ -2620,17 +2599,16 @@ def values_within_deviation(array: list, allowed_deviation: float): 100.0, 100.0, ], - "sackSize": 25, - }, - { - "id": "6s", - "co2": 1000, - "cost": 100, - "environmental": "Green", - "sack_size": 25, - "supplier": "Neil", - "title": "6 S", - "cumulative": [ + ), + ProductDTO( + id="6s", + co2=1000, + cost=100, + environmental="Green", + sack_size=25, + supplier="Neil", + title="6 S", + cumulative=[ 0.0, 0.0, 0.0, @@ -2733,8 +2711,7 @@ def values_within_deviation(array: list, allowed_deviation: float): 100.0, 100.0, ], - "sackSize": 25, - }, + ), ] @@ -2745,7 +2722,7 @@ def _short_test_wrapper(theoretical_bridge, density=350, max_iterations=2000, ma for _i in range(2): result = Optimizer(theoretical_bridge, product_data, density, max_iterations, max_products).optimize() result_list.append(result) - fitness = [run["score"] for run in result_list] + fitness = [result.score for result in result_list] values_within_deviation(fitness, 15) def test_deviation_short_permeability(self): @@ -2768,15 +2745,16 @@ def show_plot(): bridgeplot.set_xticks([0.1, 1, 10, 100, 1000]) bridgeplot.xaxis.set_major_formatter(ScalarFormatter()) bridgeplot.plot(SIZE_STEPS, bridge, color="black", label="ideal") - bridgeplot.axes.set_ylim([0, 100]) - bridgeplot.axes.set_xlim([0.01, 10000]) + if bridgeplot.axes: + bridgeplot.axes.set_ylim((0, 100)) + bridgeplot.axes.set_xlim((0.01, 10000)) result_list = [] for _i in range(1): result = Optimizer( products=product_data, bridge=bridge, density_goal=350, max_iterations=1000, particle_range=(10, 100) ).optimize() - bridgeplot.plot(SIZE_STEPS, result["cumulative_bridge"]) + bridgeplot.plot(SIZE_STEPS, result.cumulative_bridge) result_list.append(result) fig.show() @@ -2818,12 +2796,12 @@ def create_algorithm_report(): for i in range(runs): result = Optimizer(permeability_bridge, product_data, density, max_iterations).optimize() result_list.append(result) - label = f"{i}-{round(result['score'], 1)}" - bridgeplot.plot(SIZE_STEPS, result["cumulative_bridge"]) - permeability.plot(result["curve"], label=label) + label = f"{i}-{round(result.score, 1)}" + bridgeplot.plot(SIZE_STEPS, result.cumulative_bridge) + permeability.plot(result.curve, label=label) print(f"{i + 1} of {runs} runs complete...") - fitness = [run["score"] for run in result_list] + fitness = [run.score for run in result_list] standard_deviation = round(float(np.std(fitness)), 4) permeability.text( 0.975, @@ -2875,12 +2853,12 @@ def create_algorithm_report(): for i in range(runs): result = Optimizer(m_pore_bridge, product_data, density, max_iterations).optimize() result_list.append(result) - label = f"{i}-{round(result['score'], 1)}" - bridgeplot.plot(SIZE_STEPS, result["cumulative_bridge"]) - m_poresize.plot(result["curve"], label=label) + label = f"{i}-{round(result.score, 1)}" + bridgeplot.plot(SIZE_STEPS, result.cumulative_bridge) + m_poresize.plot(result.curve, label=label) print(f"{i + 1} of {runs} runs complete...") - fitness = [run["score"] for run in result_list] + fitness = [run.score for run in result_list] standard_deviation = round(float(np.std(fitness)), 4) m_poresize.text( 0.975, @@ -2932,12 +2910,12 @@ def create_algorithm_report(): for i in range(runs): result = Optimizer(avg_pore_bridge, product_data, density, max_iterations).optimize() result_list.append(result) - label = f"{i}-{round(result['score'], 1)}" - bridgeplot.plot(SIZE_STEPS, result["cumulative_bridge"]) - avg_poresize.plot(result["curve"], label=label) + label = f"{i}-{round(result.score, 1)}" + bridgeplot.plot(SIZE_STEPS, result.cumulative_bridge) + avg_poresize.plot(result.curve, label=label) print(f"{i + 1} of {runs} runs complete...") - fitness = [run["score"] for run in result_list] + fitness = [run.score for run in result_list] standard_deviation = round(float(np.std(fitness)), 4) avg_poresize.text( 0.975, diff --git a/api/src/tests/test_calculate_performance.py b/api/src/tests/test_calculate_performance.py index e8a63fa5..3443e651 100644 --- a/api/src/tests/test_calculate_performance.py +++ b/api/src/tests/test_calculate_performance.py @@ -5,19 +5,22 @@ from classes.product import Product from tests.optimizer_test import product_data from util.enums import BridgeOption +from util.exceptions import InternalErrorException products_result: list[Product] = [] volume = 10 combination = {"1b": 10, "1l": 20, "1s": 1} for p in product_data: - if p["id"] in combination: + if p.id in combination: + if p.cumulative is None: + raise InternalErrorException(f"Product {p.id} does not have cumulative distribution data") products_result.append( Product( - product_id=p["id"], - share=(combination[p["id"]] / sum(combination.values())) * 100, - cumulative=p["cumulative"], - sacks=combination[p["id"]], - mass=(combination[p["id"]] * volume), + product_id=p.id, + share=(combination[p.id] / sum(combination.values())) * 100, + cumulative=p.cumulative, + sacks=combination[p.id], + mass=(combination[p.id] * volume), ) ) @@ -133,6 +136,7 @@ def test_calculate_performance_normal_values(): particle_range = (1.01, 100.0) performance = Optimizer( bridge=theoretical_bridge(BridgeOption.PERMEABILITY, 500), + products=[], max_products=products_goal, density_goal=density_goal, particle_range=particle_range, @@ -249,6 +253,7 @@ def test_calculate_performance_tripple_values(): particle_range = (1.01, 100.0) performance = Optimizer( bridge=theoretical_bridge(BridgeOption.PERMEABILITY, 500), + products=[], max_products=products_goal, density_goal=density_goal, particle_range=particle_range, @@ -365,6 +370,7 @@ def test_calculate_performance_zero_values(self): performance = Optimizer( bridge=theoretical_bridge(BridgeOption.PERMEABILITY, 500), + products=[], max_products=products_goal, density_goal=density_goal, particle_range=particle_range, @@ -378,6 +384,7 @@ def test_calculate_performance_perfect_bridge(): particle_range = (1.01, 100.0) performance = Optimizer( bridge=theoretical_bridge(BridgeOption.PERMEABILITY, 500), + products=[], max_products=products_goal, density_goal=density_goal, particle_range=particle_range, diff --git a/api/src/tests/test_interpolator.py b/api/src/tests/test_interpolator.py deleted file mode 100644 index acd73e28..00000000 --- a/api/src/tests/test_interpolator.py +++ /dev/null @@ -1,44 +0,0 @@ -import unittest - -from calculators.fraction_interpolator import fraction_interpolator - - -class InterpolatorTest(unittest.TestCase): - @staticmethod - def test_interpolator(): - a_x = [ - 34.673685, - 39.810717, - 45.708819, - 52.480746, - 60.255959, - 69.183097, - 79.432823, - 91.201084, - 104.712855, - 120.226443, - 138.038426, - 158.489319, - 181.970086, - 208.929613, - ] - a_y = [ - 0.188712124, - 0.213878447, - 0.501295532, - 0.914227642, - 1.467265554, - 2.332118964, - 5.24412729, - 10.27170641, - 16.6393325, - 23.31980528, - 28.90886759, - 32.59114256, - 34.53416106, - 35.88136905, - ] - - b_x = [39.8, 60.2, 104.7] - b_y = fraction_interpolator(x=a_x, y=a_y, z=b_x) - assert b_y == [0.214, 1.464, 16.634] diff --git a/api/src/tests/test_report.py b/api/src/tests/test_report.py index 79e62bbf..e9786099 100644 --- a/api/src/tests/test_report.py +++ b/api/src/tests/test_report.py @@ -1,8 +1,7 @@ -import unittest from pathlib import Path -from unittest import skip +from unittest import TestCase, skip -from controllers.report import create_report +from use_cases.create_report import create_report request = { "fitness": 4.4, @@ -328,7 +327,7 @@ @skip("No time to fix") -class ReportTest(unittest.TestCase): +class ReportTest(TestCase): @staticmethod def test_create_report(): result = Path(create_report(request, bridge=False)) diff --git a/web/src/Components/Optimization/styles.ts b/api/src/use_cases/__init__.py similarity index 100% rename from web/src/Components/Optimization/styles.ts rename to api/src/use_cases/__init__.py diff --git a/api/src/controllers/combination.py b/api/src/use_cases/bridge_from_combination.py similarity index 65% rename from api/src/controllers/combination.py rename to api/src/use_cases/bridge_from_combination.py index 2eb6444a..4ea2e294 100644 --- a/api/src/controllers/combination.py +++ b/api/src/use_cases/bridge_from_combination.py @@ -4,21 +4,25 @@ from calculators.bridge import calculate_blend_cumulative from classes.product import Product -from controllers.products import products_get +from use_cases.get_products import retrieve_products +from util.exceptions import InternalErrorException def bridge_from_combination(combination: list[dict]): - all_products = products_get() + all_products = retrieve_products() sum_sacks = sum([p["value"] for p in combination]) product_list = [] for p in combination: if p["value"] <= 0: continue + product_dto = all_products[p["id"]] + if product_dto.cumulative is None: + raise InternalErrorException(f"Product {p['id']} does not have cumulative distribution data") product_list.append( Product( product_id=p["id"], share=(100 / sum_sacks * p["value"]) / 100, - cumulative=all_products[p["id"]]["cumulative"], + cumulative=product_dto.cumulative, ) ) bridge = calculate_blend_cumulative(product_list) diff --git a/api/src/controllers/optimal_bridge.py b/api/src/use_cases/calculate_optimal_bridge.py similarity index 60% rename from api/src/controllers/optimal_bridge.py rename to api/src/use_cases/calculate_optimal_bridge.py index f7a3bd8b..bd6a518a 100644 --- a/api/src/controllers/optimal_bridge.py +++ b/api/src/use_cases/calculate_optimal_bridge.py @@ -3,9 +3,8 @@ from calculators.bridge import theoretical_bridge -def bridgeRequestHandler(option: str, value: int): +def calculate_optimal_bridge(option: str, value: int): if not value or not option: return Response("No options or value given!", 400) bridge = theoretical_bridge(option, value) - response_dict = {"bridge": [round(num, 1) for num in bridge]} - return response_dict + return {"bridge": [round(num, 1) for num in bridge]} diff --git a/api/src/controllers/report.py b/api/src/use_cases/create_report.py similarity index 64% rename from api/src/controllers/report.py rename to api/src/use_cases/create_report.py index 7ccd677a..6403f334 100644 --- a/api/src/controllers/report.py +++ b/api/src/use_cases/create_report.py @@ -1,5 +1,6 @@ import subprocess import tempfile +from dataclasses import dataclass from datetime import datetime from plots.bridge import bridge_plot @@ -7,48 +8,53 @@ from plots.products_pie import products_pie +@dataclass class Weighting: - def __init__(self, fit: int, mass: int, products: int, cost: int, co2: int, environmental: int): - self.fit = fit - self.mass = mass - self.products = products - self.cost = cost - self.co2 = co2 - self.environmental = environmental + fit: int + mass: int + products: int + cost: int | None + co2: int | None + environmental: int | None +@dataclass class Report: - score: float = None - curve: list[float] = None - pill_volume: int = None - pill_density: int = None - bridging_mode: str = None - bridging_value: int = None - total_mass: int = None - products: dict = None - weighting: Weighting = None - email: str = None - user: str = None + score: float + curve: list[float] + pill_volume: int + pill_density: int + bridging_mode: str + bridging_value: int + total_mass: int + products: dict + weighting: Weighting + email: str + user: str @classmethod - def from_dict(cls, _dict: dict): - instance = cls() - instance.score = _dict["fitness"] - instance.curve = _dict["curve"] - instance.email = _dict["email"] - instance.user = _dict["user"] - instance.pill_volume = _dict["pillVolume"] - instance.pill_density = _dict["pillDensity"] - instance.bridging_mode = _dict["bridgingMode"] - instance.bridging_value = _dict["bridgingValue"] - instance.total_mass = _dict["totalMass"] - instance.products = _dict["products"] - instance.weighting = Weighting( - _dict["weighting"]["bridge"], _dict["weighting"]["mass"], _dict["weighting"]["products"], None, None, None + def from_request_dict(cls, request: dict) -> "Report": + return cls( + score=request["fitness"], + curve=request["curve"], + pill_volume=request["pillVolume"], + pill_density=request["pillDensity"], + bridging_mode=request["bridgingMode"], + bridging_value=request["bridgingValue"], + total_mass=request["totalMass"], + products=request["products"], + weighting=Weighting( + request["weighting"]["bridge"], + request["weighting"]["mass"], + request["weighting"]["products"], + None, + None, + None, + ), + email=request["email"], + user=request["user"], ) - return instance - def as_html(report: Report, pie_chart, bridge_graph, fitness_plot) -> str: date_stamp = datetime.now().strftime("%d.%m.%Y %H:%M") @@ -56,7 +62,8 @@ def as_html(report: Report, pie_chart, bridge_graph, fitness_plot) -> str: combinations = "" for p in report.products.values(): - combinations += f""" + combinations += f""" + {p["id"]} {p["value"]} {round(p["percentage"], 2)}% @@ -95,7 +102,7 @@ def as_html(report: Report, pie_chart, bridge_graph, fitness_plot) -> str: def create_report(request: dict, bridge: bool = True): - report: Report = Report().from_dict(request) + report = Report.from_request_dict(request) pie_chart = products_pie(report.products) bridge_graph = bridge_plot(report.products, report.bridging_mode, report.bridging_value) if bridge else "" fitness_plot = evolution_plot(report.curve) @@ -103,6 +110,7 @@ def create_report(request: dict, bridge: bool = True): with tempfile.NamedTemporaryFile("w") as html_file: html_file.write(html) + html_file.flush() try: subprocess.run( # noqa: S602 [f"pandoc {html_file.name} -f html -o {OUT_PDF}"], diff --git a/api/src/use_cases/get_products.py b/api/src/use_cases/get_products.py new file mode 100644 index 00000000..b040b29b --- /dev/null +++ b/api/src/use_cases/get_products.py @@ -0,0 +1,64 @@ +import json +from dataclasses import asdict, dataclass + +from cachetools import TTLCache, cached + +from config import Config +from util.azure_table import get_service +from util.exceptions import InternalErrorException +from util.utils import convert_keys_underscore_to_camel + + +@dataclass +class ProductDTO: + id: str + title: str + supplier: str + co2: float + cost: float + environmental: str + sack_size: int + cumulative: list[float] | None + + @classmethod + def from_db_entity(cls, entity) -> "ProductDTO": + cumulative = json.loads(entity.get("cumulative")) if entity.get("cumulative") else None + return cls( + id=entity.id, + title=entity.title, + supplier=entity.supplier, + co2=entity.co2, + cost=entity.cost, + environmental=entity.environmental, + sack_size=entity.sack_size, + cumulative=cumulative, + ) + + +def _sort_product_dict(products: dict[str, ProductDTO]) -> dict[str, ProductDTO]: + values = list(products.values()) + values.sort(key=lambda p: (p.supplier, p.id)) + + return {v.id: v for v in values} + + +def retrieve_products() -> dict[str, ProductDTO]: + products = get_service().query_entities(Config.PRODUCT_TABLE_NAME) + + products_response = {} + for p in products: + product_dto = ProductDTO.from_db_entity(p) + products_response[p.RowKey] = product_dto + + sorted_products = _sort_product_dict(products_response) + + if not len(sorted_products): + raise InternalErrorException("No products found in storage") + + return sorted_products + + +@cached(cache=TTLCache(maxsize=128, ttl=300)) +def get_products(): + products_response = retrieve_products() + return convert_keys_underscore_to_camel({k: asdict(v) for k, v in products_response.items()}) diff --git a/api/src/use_cases/run_optimizer.py b/api/src/use_cases/run_optimizer.py new file mode 100644 index 00000000..f6c01eee --- /dev/null +++ b/api/src/use_cases/run_optimizer.py @@ -0,0 +1,131 @@ +from dataclasses import asdict, dataclass, field + +from calculators.bridge import theoretical_bridge +from calculators.optimizer import Optimizer, OptimizerWeights +from classes.product import Product +from use_cases.get_products import retrieve_products +from util.exceptions import InternalErrorException, ValidationException + + +@dataclass +class OptimizerParameterProduct: + id: str + title: str + supplier: str + environmental: str + sack_size: int + co2: int + cost: int + cumulative: list[float] + + +@dataclass +class OptimizerParameters: + request: str + name: str + value: float + products: dict[str, OptimizerParameterProduct] + density: float + volume: float + option: str = "AVERAGE_PORESIZE" + iterations: int = 500 + max_products: int = 999 + particle_range: tuple[float, float] = (1.0, 100) + weights: OptimizerWeights = field(default_factory=lambda: OptimizerWeights(bridge=5, mass=5, products=5)) + + def __post_init__(self): + if self.iterations <= 0: + raise ValidationException("Number of iterations must be a positive integer") + if self.particle_range[0] >= self.particle_range[1]: + raise ValidationException("Particle size 'from' must be smaller than 'to'") + if self.max_products == 0: + self.max_products = 999 + if type(self.weights) is dict: + self.weights = OptimizerWeights(**self.weights) + + +@dataclass +class OptimizerResultConfiguration: + iterations: int + value: float + mode: str + + +@dataclass +class OptimizerResultProduct: + id: str + value: float + + +@dataclass +class OptimizerResult: + name: str + config: OptimizerResultConfiguration + products: dict[str, OptimizerResultProduct] + performance: dict + totalMass: float + cumulative: list[float] + executionTime: int + fitness: float + weighting: OptimizerWeights + curve: list[float] + bridgeScore: float + + +def run_optimizer(parameter_dict: dict) -> dict: + parameters = OptimizerParameters(**parameter_dict) + + print(f"Started optimization request with {parameters.iterations} maximum iterations...") + bridge = theoretical_bridge(parameters.option, parameters.value) + selected_products = [p for p in retrieve_products().values() if p.id in parameters.products] + if len(selected_products) < 2: + raise ValidationException("Can not run the optimizer with less than two products") + + optimizer = Optimizer( + bridge=bridge, + products=selected_products, + density_goal=parameters.density, + volume=parameters.volume, + max_iterations=parameters.iterations, + max_products=parameters.max_products, + particle_range=parameters.particle_range, + weights=parameters.weights, + ) + optimizer_result = optimizer.optimize() + combination = optimizer_result.combination + + products_result: list[Product] = [] + for p in selected_products: + if p.id in combination.keys(): + if p.cumulative is None: + raise InternalErrorException(f"Product {p.id} does not have cumulative distribution data") + products_result.append( + Product( + product_id=p.id, + share=combination[p.id] / sum(combination.values()), + cumulative=p.cumulative, + sacks=combination[p.id], + mass=(combination[p.id] * parameters.volume), + ) + ) + + return asdict( + OptimizerResult( + name=parameters.name, + config=OptimizerResultConfiguration( + iterations=optimizer_result.iterations, value=parameters.value, mode=parameters.option + ), + products={id: OptimizerResultProduct(id=id, value=combination[id]) for id in combination}, + performance=optimizer.calculate_performance( + experimental_bridge=optimizer_result.cumulative_bridge, + products_result=products_result, + ), + totalMass=round(sum([p.mass for p in products_result]), 1), + cumulative=optimizer_result.cumulative_bridge, + executionTime=int(optimizer_result.execution_time.microseconds / 1000), + fitness=optimizer_result.score, + weighting=parameters.weights, + curve=optimizer_result.curve, + bridgeScore=optimizer_result.bridge_score, + ) + ) diff --git a/api/src/util/sync_share_point_az.py b/api/src/use_cases/synchronize_with_sharepoint.py similarity index 75% rename from api/src/util/sync_share_point_az.py rename to api/src/use_cases/synchronize_with_sharepoint.py index 0f37b2d3..5c5deea5 100644 --- a/api/src/util/sync_share_point_az.py +++ b/api/src/use_cases/synchronize_with_sharepoint.py @@ -1,3 +1,4 @@ +import logging from datetime import datetime from time import sleep @@ -9,23 +10,28 @@ from config import Config from util.azure_blobs import get_metadata_blob_data, get_product_blobs_data from util.azure_table import create_table +from util.exceptions import InternalErrorException + +_logger = logging.getLogger("API") def sync_sharepoint_and_az_blobs(): + if not Config.SYNC_BLOBS_APP_URL: + raise InternalErrorException("SYNC_BLOBS_APP_URL is not configured") request = requests.get(Config.SYNC_BLOBS_APP_URL, timeout=30) request.raise_for_status() - print(f"Triggered Logic App by HTTP request for url; {Config.SYNC_BLOBS_APP_URL}") + _logger.info("Triggered Logic App sync") def delete_all_entries_in_table(table_service, table_name): entities = [] try: - entities = table_service.query_entities(table_name) + entities = list(table_service.query_entities(table_name)) except AzureMissingResourceHttpError: - pass + _logger.info(f"Table '{table_name}' does not exist, skipping deletion") for t in entities: table_service.delete_entity(table_name, table_name, t.RowKey) - print(f"Deleted all rows in '{table_name}' table") + _logger.info(f"Deleted all rows in '{table_name}' table") def sync_excel_blobs_and_az_tables(): @@ -46,19 +52,20 @@ def sync_excel_blobs_and_az_tables(): batch.insert_entity(p) try: table_service.commit_batch(table_name=Config.PRODUCT_TABLE_NAME, batch=batch) - print( + _logger.info( f"Uploaded products data to '{Config.PRODUCT_TABLE_NAME}' table in '{Config.TABLE_ACCOUNT_NAME}' storage account" ) except HeaderParsingError as e: - print(e) + _logger.warning(f"HeaderParsingError during batch commit: {e}") -def sync_all(): +def synchronize_with_sharepoint(): start = datetime.now() sync_sharepoint_and_az_blobs() # TODO: Use callBack from LogicApp to know when done/succeeded sleep(50) sync_excel_blobs_and_az_tables() end = datetime.now() - start - print(f"The sync took {end.seconds} seconds") + _logger.info(f"The sync completed in {end.total_seconds()} seconds") + return "ok" diff --git a/api/src/util/authentication.py b/api/src/util/authentication.py index 3c6d191d..c54345be 100644 --- a/api/src/util/authentication.py +++ b/api/src/util/authentication.py @@ -1,60 +1,46 @@ -import json -from functools import wraps +import logging import jwt import requests from cachetools import TTLCache, cached from flask import abort, g, request -from jwt.algorithms import RSAAlgorithm from classes.user import User from config import Config from util.exceptions import AuthenticationException +_logger = logging.getLogger("API") -@cached(cache=TTLCache(maxsize=128, ttl=86400)) -def get_cert(key_id): - """ - Fetches JSON-Web-Keys from the env AUTH_JWK_URL url - Returns a RSA PEM byte object from the key with the same 'kid' as the token. - Time-To-Live cache that expires every 24h - """ + +@cached(cache=TTLCache(maxsize=1, ttl=86400)) +def _get_jwk_client() -> jwt.PyJWKClient: try: - jwks = requests.get(Config.AUTH_JWK_URL, timeout=30).json()["keys"] - return next(RSAAlgorithm.from_jwk(json.dumps(key)) for key in jwks if key["kid"] == key_id) + oid_conf = requests.get(Config.AUTH_OIDC_WELL_KNOWN, timeout=30).json() + return jwt.PyJWKClient(oid_conf["jwks_uri"]) except requests.RequestException as error: + _logger.error(f"Failed to fetch OpenId Connect configuration for '{Config.AUTH_OIDC_WELL_KNOWN}': {error}") raise AuthenticationException(str(error)) from error -def decode_jwt(token): +def decode_jwt(token: str) -> dict: try: - # If Auth is configured with a secret, we use that to decode the token if Config.AUTH_SECRET: - decoded_token = jwt.decode(token, Config.AUTH_SECRET, algorithms="HS256", audience=Config.AUTH_JWT_AUDIENCE) - # If no secret provided, fallback to RSA based token signing. - else: - cert = get_cert(jwt.get_unverified_header(token)["kid"]) - decoded_token = jwt.decode(token, cert, algorithms="RS256", audience=Config.AUTH_JWT_AUDIENCE) - # Add a user object to the global flask context - g.user = User(**decoded_token) - return decoded_token + return jwt.decode(token, Config.AUTH_SECRET, algorithms=["HS256"], audience=Config.AUTH_JWT_AUDIENCES) + signing_key = _get_jwk_client().get_signing_key_from_jwt(token).key + options = {"algorithms": ["RS256"], "audience": Config.AUTH_JWT_AUDIENCES} + if Config.AUTH_JWT_ISSUER: + options["issuer"] = Config.AUTH_JWT_ISSUER + return jwt.decode(token, signing_key, **options) except Exception as e: raise AuthenticationException(str(e)) from e -def authorize(f): - @wraps(f) - def wrap(*args, **kwargs): - if "Authorization" not in request.headers: - abort(401, "Missing 'Authorization' header") - try: - token = request.headers["Authorization"].split(" ", 1)[1] - decode_jwt(token) - except (AuthenticationException, IndexError, Exception) as e: - print(f"AUTH ERROR: {e}") - # Return a generic auth error, no specifics - abort(401, "Failed to authorize the request") - - return f(*args, **kwargs) - - return wrap +def authenticate_request() -> None: + if "Authorization" not in request.headers: + abort(401, "Missing 'Authorization' header") + try: + token = request.headers["Authorization"].split(" ", 1)[1] + g.user = User.from_jwt(decode_jwt(token)) + except Exception as e: + _logger.warning("Auth failure: %s", e) + abort(401, "Failed to authorize the request") diff --git a/api/src/util/azure_table.py b/api/src/util/azure_table.py index a5e57098..e6b7e6f2 100644 --- a/api/src/util/azure_table.py +++ b/api/src/util/azure_table.py @@ -1,14 +1,17 @@ import csv import json +import logging from datetime import datetime, timedelta from time import sleep -from typing import io +from typing import TextIO from azure.common import AzureConflictHttpError from azure.cosmosdb.table.tableservice import TableService from config import Config +_logger = logging.getLogger("API") + def _wait_for_table_to_be_created(table_service: TableService, table_name: str) -> bool: timer = datetime.now() @@ -17,15 +20,12 @@ def _wait_for_table_to_be_created(table_service: TableService, table_name: str) try: table_service.create_table(table_name, fail_on_exist=True) is_created = True - print(f"Created table '{table_name}'") + _logger.info("Created table '%s'", table_name) except AzureConflictHttpError as e: if datetime.now() - timer > timedelta(minutes=5): - print(e) - print(f"Could not crate {table_name} in 5 minutes") - print("Giving up") - print("Could not create Azure Table!") + _logger.error("Could not create table '%s' within 5 minutes: %s", table_name, e) break - print("Retrying in 5 seconds...") + _logger.info("Table '%s' not ready yet, retrying in 5 seconds...", table_name) sleep(5) return is_created @@ -39,7 +39,7 @@ def create_table(table_service: TableService, table_name: str): Note that deleting a table is likely to take at least 40 seconds to complete. """ table_service.delete_table(table_name) - print(f"Deleted table '{table_name}'") + _logger.info("Deleted table '%s'", table_name) _wait_for_table_to_be_created(table_service, table_name) @@ -51,7 +51,7 @@ def get_service(): return TableService(account_name=Config.TABLE_ACCOUNT_NAME, account_key=Config.TABLE_KEY) -def process_meta_blob(meta_file: io.TextIO) -> list[dict]: +def process_meta_blob(meta_file: TextIO) -> list[dict]: reader = csv.DictReader(meta_file) products = [] @@ -62,7 +62,7 @@ def process_meta_blob(meta_file: io.TextIO) -> list[dict]: "RowKey": sanitize_row_key(row["title"]), "id": sanitize_row_key(row["title"]), **row, - "supplier": row["supplier"] if row["supplier"] in Config.named_supplier else "Other", + "supplier": row["supplier"] if row["supplier"] in Config.NAMED_SUPPLIERS else "Other", # TODO: Prod data is missing co2 impact "co2": row["co2"] if row["co2"] else 1000, # TODO: Prod data is missing cost diff --git a/api/src/util/enums.py b/api/src/util/enums.py index a7511896..e5c29b0a 100644 --- a/api/src/util/enums.py +++ b/api/src/util/enums.py @@ -1,4 +1,7 @@ -class BridgeOption: +from enum import StrEnum + + +class BridgeOption(StrEnum): MAXIMUM_PORESIZE = "MAXIMUM_PORESIZE" AVERAGE_PORESIZE = "AVERAGE_PORESIZE" PERMEABILITY = "PERMEABILITY" diff --git a/api/src/util/exception_handling.py b/api/src/util/exception_handling.py new file mode 100644 index 00000000..d897918d --- /dev/null +++ b/api/src/util/exception_handling.py @@ -0,0 +1,23 @@ +import functools +import logging + +from flask import Response + +from util.exceptions import InternalErrorException, ValidationException + + +def handle_exceptions(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + try: + return func(*args, **kwargs) + except ValidationException as e: + return Response(f"Validation error: {e.message}", status=400) + except InternalErrorException as e: + logging.getLogger("API").exception("Internal error occurred", exc_info=e) + return Response(f"Internal error: {e.message}", status=500) + except Exception as e: + logging.getLogger("API").exception("Unexpected error occurred", exc_info=e) + return Response("Internal error: An unexpected error occurred", status=500) + + return wrapper diff --git a/api/src/util/exceptions.py b/api/src/util/exceptions.py index a096b862..1ecc8363 100644 --- a/api/src/util/exceptions.py +++ b/api/src/util/exceptions.py @@ -1,9 +1,19 @@ class CustomException(Exception): def __init__(self, message: str): - super() self.message = message + super().__init__(message) class AuthenticationException(CustomException): def __init__(self, message): super().__init__(message=message) + + +class ValidationException(CustomException): + def __init__(self, message): + super().__init__(message=message) + + +class InternalErrorException(CustomException): + def __init__(self, message): + super().__init__(message=message) diff --git a/api/src/util/logging.py b/api/src/util/logging.py new file mode 100644 index 00000000..9b5767e4 --- /dev/null +++ b/api/src/util/logging.py @@ -0,0 +1,23 @@ +import logging +import os + +from azure.monitor.opentelemetry import configure_azure_monitor +from flask import Flask +from opentelemetry.instrumentation.flask import FlaskInstrumentor + +from config import Config + + +def init_logging(flask_app: Flask): + logger = logging.getLogger("API") + if logger.hasHandlers(): + logger.handlers.clear() + logger.setLevel(logging.INFO) + handler = logging.StreamHandler() + handler.setFormatter(logging.Formatter("%(levelname)s: %(asctime)s %(message)s")) + logger.addHandler(handler) + if os.getenv("FLASK_DEBUG") is None: + FlaskInstrumentor.instrument_app(flask_app) + configure_azure_monitor(connection_string=Config.APPINSIGHTS_CON_STRING, logger_name="API") + + logger.info("Logger is configured") diff --git a/api/src/util/utils.py b/api/src/util/utils.py index 3dde9fa3..9cc90d3f 100644 --- a/api/src/util/utils.py +++ b/api/src/util/utils.py @@ -1,4 +1,29 @@ -def print_progress(i: int, goal: int): - if i != 0 and i % 100 == 0: - progress = round(100 / goal * i, 2) - print(f"Progress: {progress}%") +import re + + +def camel_to_underscore(name): + """Convert camelCase to snake_case.""" + camel_case_pattern = re.compile(r"([A-Z])") + return camel_case_pattern.sub(lambda x: "_" + x.group(1).lower(), name) + + +def underscore_to_camel(name): + """Convert snake_case to camelCase.""" + snake_case_pattern = re.compile(r"_([a-z])") + return snake_case_pattern.sub(lambda x: x.group(1).upper(), name) + + +def convert_keys_camel_to_underscore(data: dict) -> dict: + """Recursively convert all keys in a dictionary from camelCase to snake_case.""" + return { + camel_to_underscore(k): convert_keys_camel_to_underscore(v) if isinstance(v, dict) else v + for k, v in data.items() + } + + +def convert_keys_underscore_to_camel(data: dict) -> dict: + """Recursively convert all keys in a dictionary from snake_case to camelCase.""" + return { + underscore_to_camel(k): convert_keys_underscore_to_camel(v) if isinstance(v, dict) else v + for k, v in data.items() + } diff --git a/api/util/report.css b/api/util/report.css deleted file mode 100644 index 9f5f3dcf..00000000 --- a/api/util/report.css +++ /dev/null @@ -1,14 +0,0 @@ -table { - font-family: arial, sans-serif; - border-collapse: collapse; -} - -td, th { - border: 1px solid #dddddd; - text-align: left; - padding:0 8px 0 8px; -} - -tr:nth-child(even) { - background-color: #dddddd; -} \ No newline at end of file diff --git a/web/biome.jsonc b/biome.jsonc similarity index 73% rename from web/biome.jsonc rename to biome.jsonc index 72b7a230..0b330926 100644 --- a/web/biome.jsonc +++ b/biome.jsonc @@ -1,22 +1,18 @@ { - "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", + "$schema": "https://biomejs.dev/schemas/2.4.4/schema.json", "files": { - "ignore": [ - "node_modules" - ] + "includes": ["**/*.ts", "**/*.tsx", "**/*.json", "**/*.jsonc", "!node_modules"] }, "formatter": { "indentStyle": "space", + "indentWidth": 2, "lineWidth": 120 }, "javascript": { "formatter": { "semicolons": "asNeeded", "quoteStyle": "single", - "indentStyle": "space", - "indentWidth": 2, - "trailingCommas": "es5", - "lineWidth": 120 + "trailingCommas": "es5" } }, "linter": { @@ -38,4 +34,4 @@ } } } -} \ No newline at end of file +} diff --git a/catalog-info.yaml b/catalog-info.yaml new file mode 100644 index 00000000..4551c283 --- /dev/null +++ b/catalog-info.yaml @@ -0,0 +1,129 @@ +apiVersion: backstage.io/v1alpha1 +kind: System +metadata: + name: lcm + title: Lost Circulation Material + description: Web application for creating, comparing, and optimize blending of lost circulation material used to bridge fractures and stop losses in rock formations during petroleum drilling. + annotations: + github.com/project-slug: equinor/lcm + backstage.io/techdocs-ref: dir:. + equinor.com/techdocs-builder: host + links: + - url: "https://lost-circulation-material.app.radix.equinor.com/" + title: "Production environment" + icon: star + - url: "https://proxy-lost-circulation-material-test.radix.equinor.com/" + title: "Test environment" + icon: unstarred + - url: "https://console.radix.equinor.com/applications/lost-circulation-material" + title: "Radix console" + icon: dashboard + - url: "https://statoilsrm.sharepoint.com/sites/LCMlibrary/Lists/Product" + title: "LCM library in SharePoint" + icon: library +spec: + type: product + lifecycle: production + owner: team-hermes +--- +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: lcm-api + title: LCM API + description: Flask backend for LCM application. + tags: + - backend + - api + - flask + - python + annotations: + github.com/project-slug: equinor/lcm + backstage.io/techdocs-entity: system:default/lcm + +spec: + type: service + lifecycle: production + owner: team-hermes + system: system:default/lcm + providesApis: + - lcm-api + dependsOn: + - resource:default/lcm-database + - resource:default/lcm-blob-storage +--- +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: lcm-frontend + title: LCM Frontend + description: React frontend application for LCM. + tags: + - frontend + - react + - typescript + annotations: + github.com/project-slug: equinor/lcm + backstage.io/techdocs-entity: system:default/lcm + links: + - url: "https://lost-circulation-material.app.radix.equinor.com/" + title: "LCM Application" + icon: app +spec: + type: website + lifecycle: production + owner: team-hermes + system: system:default/lcm + consumesApis: + - lcm-api + dependsOn: + - component:default/lcm-api +--- +apiVersion: backstage.io/v1alpha1 +kind: Resource +metadata: + name: lcm-database + title: LCM Database + description: Azure Tables database for LCM. + annotations: + github.com/project-slug: equinor/lcm + backstage.io/techdocs-entity: system:default/lcm +spec: + type: database + lifecycle: production + owner: team-hermes + system: system:default/lcm +--- +apiVersion: backstage.io/v1alpha1 +kind: Resource +metadata: + name: lcm-blob-storage + title: LCM Blob Storage + description: Azure Blob Storage for LCM. + annotations: + github.com/project-slug: equinor/lcm + backstage.io/techdocs-entity: system:default/lcm +spec: + type: database + lifecycle: production + owner: team-hermes + system: system:default/lcm + dependsOn: + - resource:default/lcm-sharepoint + +--- +apiVersion: backstage.io/v1alpha1 +kind: Resource +metadata: + name: lcm-sharepoint + title: LCM SharePoint + description: SharePoint storage for LCM. + annotations: + github.com/project-slug: equinor/lcm + backstage.io/techdocs-entity: system:default/lcm +spec: + type: database + lifecycle: production + owner: Equinor + system: system:default/lcm +--- diff --git a/docker-compose.yaml b/docker-compose.yaml index 86b962b0..e1f6d835 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -6,7 +6,26 @@ services: - "80:8080" depends_on: - web + - oauth2-proxy + redis: + build: ./redis + restart: unless-stopped + environment: + REDIS_PASSWORD: 'very secret' + oauth2-proxy: + build: ./oauth2 + depends_on: + redis: + condition: service_healthy + environment: + OAUTH2_PROXY_REDIS_PASSWORD: 'very secret' + OAUTH2_PROXY_COOKIE_SECRET: 'vry secure cokie' # cookie_secret must be 16, 24, or 32 bytes + OAUTH_CLIENT_ID: "1dbc1e96-268d-41ad-894a-92a9fb85f954" + OAUTH2_PROXY_REDIRECT_URL: http://localhost/oauth2/callback + CLIENT_SECRET_FILE: /run/secrets/client_secret + secrets: + - client_secret api: build: context: ./api @@ -15,8 +34,7 @@ services: ENVIRONMENT: development FLASK_DEBUG: "true" TABLE_KEY: ${TABLE_KEY} - ports: - - "5000:5000" + APPINSIGHTS_CON_STRING: ${APPINSIGHTS_CON_STRING} volumes: - ./api/src:/app/src @@ -24,8 +42,16 @@ services: build: context: ./web target: development + args: + APPINSIGHTS_CON_STRING: ${APPINSIGHTS_CON_STRING} restart: unless-stopped stdin_open: true + environment: + HMR_CLIENT_PORT: ${HMR_CLIENT_PORT:-} + USE_POLLING: ${USE_POLLING:-false} volumes: - ./web/src:/code/src - \ No newline at end of file +secrets: + client_secret: + file: ./secrets/client_secret.txt + \ No newline at end of file diff --git a/docs/developers/guide/index.md b/docs/developers/guide/index.md new file mode 100644 index 00000000..114bb832 --- /dev/null +++ b/docs/developers/guide/index.md @@ -0,0 +1,51 @@ +# Developer Guide + +Welcome to the LCM Optimizer developer guide. This section covers everything you need to get started contributing to the project. + +## Contents + +- [Setup](setup.md) — Installing prerequisites and configuring your development environment +- [Running](running.md) — How to build and run the application locally +- [Testing](testing.md) — Running tests, linting, and code quality tools +- [Upgrading](upgrading.md) — Keeping dependencies up to date + +## Prerequisites + +Before you begin, make sure you have the following tools installed: + +### Required + +| Tool | Purpose | Install guide | +|------|---------|---------------| +| [Docker](https://docs.docker.com/get-docker/) | Containerized builds and local development | [docs.docker.com](https://docs.docker.com/get-docker/) | +| [Docker Compose](https://docs.docker.com/compose/install/) | Multi-container orchestration | Included with Docker Desktop | +| [Git](https://git-scm.com/) | Version control | [git-scm.com](https://git-scm.com/downloads) | +| [pre-commit](https://pre-commit.com/) | Git hook manager for code quality checks | [pre-commit.com](https://pre-commit.com/#install) | + +### Recommended (for working outside Docker) + +| Tool | Version | Purpose | +|------|---------|---------| +| [Python](https://www.python.org/) | ≥ 3.12 | API development | +| [Poetry](https://python-poetry.org/) | ≥ 2.0 | Python dependency management | +| [Node.js](https://nodejs.org/) | ≥ 25.x | Frontend development | +| [npm](https://docs.npmjs.com/) | Bundled with Node.js | Frontend package management | + +### Code quality tools + +| Tool | Scope | Purpose | +|------|-------|---------| +| [Ruff](https://docs.astral.sh/ruff/) | API | Python linter | +| [Black](https://black.readthedocs.io/) | API | Python code formatter | +| [Bandit](https://bandit.readthedocs.io/) | API | Python security linter | +| [Biome](https://biomejs.dev/) | Web | TypeScript/JavaScript linter and formatter | + +## Competence areas + +To contribute effectively, familiarity with the following technologies is recommended: + +- **Frontend**: React, TypeScript, Vite, styled-components, [Equinor EDS](https://eds.equinor.com/) +- **Backend**: Python, Flask, NumPy, Pandas, Matplotlib +- **Infrastructure**: Docker, Nginx, Radix, Azure +- **Authentication**: OAuth 2.0, JWT, Azure AD +- **Data**: Azure Table Storage, Azure Blob Storage, SharePoint diff --git a/docs/developers/guide/running.md b/docs/developers/guide/running.md new file mode 100644 index 00000000..a0a21d2f --- /dev/null +++ b/docs/developers/guide/running.md @@ -0,0 +1,70 @@ +# Running the project + +## Running with Docker Compose (recommended) + +The simplest way to run the entire stack locally is with Docker Compose. + +### Start all services + +```sh +docker compose up -d +``` + +This starts three containers: + +| Service | Port | Description | +|---------|------|-------------| +| **nginx** | [http://localhost:80](http://localhost:80) | Reverse proxy — main entry point | +| **api** | [http://localhost:5000](http://localhost:5000) | Flask API (debug mode) | +| **web** | [http://localhost:3000](http://localhost:3000) | Vite dev server | + + +## Running services individually + +### API (without Docker) + +```sh +cd api +poetry install # First time only +poetry run flask run --host=0.0.0.0 +``` + +The API starts on `http://localhost:5000`. + + +### Web (without Docker) + +```sh +cd web +npm install # First time only +npm run start +``` + +The dev server starts on `http://localhost:3000`. + +## Environment variables + +### API + +| Variable | Default | Description | +|----------|---------|-------------| +| `ENVIRONMENT` | — | Set to `development`, `test`, or `production` | +| `FLASK_DEBUG` | — | Set to `true` to enable Flask debug mode with auto-reload | +| `TABLE_KEY` | — | Azure Table Storage access key | +| `TABLE_ACCOUNT_NAME` | `lcmdevstorage` | Azure Storage account name | +| `APPINSIGHTS_CON_STRING` | — | Application Insights connection string | +| `LOAD_TEST_DATA` | `False` | Set to `True` to load test data instead of Azure data | +| `SYNC_BLOBS_APP_URL` | *(Logic App URL)* | URL to trigger the SharePoint sync Logic App | +| `AUTH_SECRET` | — | Secret for HS256 JWT validation (optional; falls back to RS256) | +| `AUTH_JWT_AUDIENCE` | `api://lost-circulation-material-api` | Expected JWT audience claim | +| `AUTH_JWK_URL` | `https://login.microsoftonline.com/common/discovery/v2.0/keys` | URL for fetching JSON Web Keys | + +### Web (build-time) + +| Variable | Description | +|----------|-------------| +| `VITE_CLIENT_ID` | Azure AD App Registration client ID | +| `VITE_SCOPES` | OAuth2 scopes requested by the frontend | +| `VITE_APPINSIGHTS_CON_STRING` | Application Insights connection string | +| `VITE_APPLICATION_OWNER` | Contact email shown in the application | + diff --git a/docs/developers/guide/setup.md b/docs/developers/guide/setup.md new file mode 100644 index 00000000..8d5b2988 --- /dev/null +++ b/docs/developers/guide/setup.md @@ -0,0 +1,21 @@ +# Setting up the project + + +## Configure environment variables + +Create a copy of the environment template and populate it with the required values: + +```sh +cp .env-template .env +``` + +Open `.env` in your editor and fill in the following variables: + +| Variable | Description | Where to find it | +|----------|-------------|------------------| +| `TABLE_KEY` | Access key for Azure Table Storage | Azure Portal → `lcmdevstorage` → Access keys | +| `APPINSIGHTS_CON_STRING` | Application Insights connection string | Azure Portal → Application Insights resource → Properties | + +> **Note:** These values are available in the `S118` Azure subscription. + + diff --git a/docs/developers/guide/testing.md b/docs/developers/guide/testing.md new file mode 100644 index 00000000..5a1e9549 --- /dev/null +++ b/docs/developers/guide/testing.md @@ -0,0 +1,22 @@ +# Testing + +## API tests + +The API uses [pytest](https://docs.pytest.org/) as its test framework. Tests are located in `api/src/tests/`. + + + +### Running tests + +With Docker: + +```sh +docker compose exec api poetry run pytest +``` + +Without Docker: + +```sh +cd api +poetry run pytest +``` diff --git a/docs/developers/guide/upgrading.md b/docs/developers/guide/upgrading.md new file mode 100644 index 00000000..d5c44021 --- /dev/null +++ b/docs/developers/guide/upgrading.md @@ -0,0 +1,64 @@ +# Upgrading packages + +## Web dependencies + +The frontend uses **npm** for dependency management. + +### Update all packages + +```sh +cd web +npm update +``` + +### Update a specific package + +```sh +cd web +npm update +``` + +### Check for outdated packages + +```sh +cd web +npm outdated +``` + + + +## API dependencies + +The API uses **Poetry** for dependency management. The configuration is in `api/pyproject.toml`. + +### Update all packages + +```sh +cd api +poetry update +``` + +### Update a specific package + +```sh +cd api +poetry update +``` + +### Check for outdated packages + +```sh +cd api +poetry show --outdated +``` + +### Add a new dependency + +```sh +cd api +# Runtime dependency +poetry add + +# Development-only dependency +poetry add --group dev +``` diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 00000000..48b5e8a9 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,56 @@ +# Lost Circulation Material Optimizer + +Welcome to the **LCM (Lost Circulation Material) Optimizer** documentation. + +## About the project + +LCM Optimizer is a web application for creating, comparing, and optimizing blending of lost circulation materials used to bridge fractures and stop losses in rock formations during petroleum drilling. + +The application allows users to: + +- **Optimize blends** — Run an optimizer that finds the best blend of products to match a theoretical bridging curve for a given fracture size. +- **Generate reports** — Export optimization results as PDF reports. +- **Synchronize data** — Keep product data in sync with the upstream SharePoint library. + +## Architecture overview + +The application consists of three main components, all deployed on [Equinor's Omnia Radix](https://www.radix.equinor.com) PaaS platform: + +| Component | Technology | Description | +|-----------|------------|-------------| +| **Web** | React, TypeScript, Vite | Single Page Application providing the user interface | +| **API** | Python, Flask, Gunicorn | Backend service handling calculations, data access, and report generation | +| **Proxy** | Nginx | Reverse proxy routing traffic to the web and API components | + +### Supporting services + +- **Azure AD** — Authentication via OAuth 2.0 / OpenID Connect +- **Azure Table Storage** — Stores product PSD data +- **Azure Blob Storage** — Stores product metadata and PSD Excel files +- **Azure Logic App** — Synchronizes data from SharePoint to Azure Storage +- **Azure Application Insights** — Monitoring and telemetry (frontend and backend) + +## Deployed environments + +| Environment | URL | Branch | +|-------------|-----|--------| +| Test | | `master` | +| Production | | `prod` | + +## Further reading + +- [Developer Guide](developers/guide/index.md) — Setting up, running, and testing the project +- [Operator Runbook](operators/runbook/authentication.md) — Authentication, configuration, and deployment + +## Links + +- [GitHub Repository](https://github.com/equinor/lcm) +- [GitHub Project Board](https://github.com/orgs/equinor/projects/641) +- [Radix Console](https://console.radix.equinor.com/applications/lost-circulation-material) +- [Architecture Contract](https://github.com/equinor/architecturecontract/blob/master/contracts/LCMLibrary.md) +- [IT Application (Configuration Item)](https://equinor.service-now.com/selfservice?id=form&table=cmdb_ci_business_app&sys_id=156e5bbd93da29d0eaf1f4527cba10e4) +- [SharePoint LCM Library](https://statoilsrm.sharepoint.com/sites/LCMlibrary) + +## License + +This project is licensed under the [MIT License](../LICENSE). diff --git a/docs/operators/runbook/architecture.md b/docs/operators/runbook/architecture.md new file mode 100644 index 00000000..475544cb --- /dev/null +++ b/docs/operators/runbook/architecture.md @@ -0,0 +1,64 @@ +# Architecture + +This document describes the system architecture of the LCM Optimizer. It provides an overview of the main components, their interactions, and the underlying technologies used in the application. + +## System overview + +```mermaid +graph TB + subgraph radix["Omnia Radix"] + direction TB + web["ReactJS SPA Frontend"] + api["Python Flask REST API"] + end + + subgraph azure["Azure Resources"] + direction TB + table["Azure Table Storage
(products table)"] + blob["Azure Blob Storage
(lcm-file-blobs container)"] + logicapp["Azure Logic App
(TransferDocsToBlob)"] + appinsights["Azure Application Insights"] + sharepoint["LCMLibrary SharePoint"] + azureadAuth["Azure AD Authentication Server"] + end + + user((User)) -- "HTTPS" --> web + + api -- "Read
product data" --> table + api -- "Read metadata
& PSD files" --> blob + api -. "Trigger sync" .-> logicapp + + logicapp -- "Copy PSD .xlsx files
& metadata.csv" --> blob + logicapp -- "Read documents
& product list" --> sharepoint + + web -. "Telemetry" .-> appinsights + api -. "Telemetry" .-> appinsights + web --> azureadAuth + api --> azureadAuth + web --> api +``` + +## Component details + +### Omnia Radix (PaaS) + +The application runs on [Omnia Radix](https://www.radix.equinor.com), Equinor's PaaS platform. Configuration is defined in [radixconfig.yaml](../../../radixconfig.yaml). + +| Component | Technology | Role | +|-----------|------------|------| +| **Web** | React, TypeScript, Vite | Single Page Application. Authenticates users via OAuth2 PKCE flow against Azure AD. | +| **API** | Python, Flask, Gunicorn | REST API handling calculations (bridging, optimization), data access, and PDF report generation.| + +### Azure Resources + +| Resource | Role | +|----------|------| +| **Azure Table Storage** | Stores processed product Particle Size Distribution (PSD) data in a `products` table. Rebuilt on each SharePoint sync. | +| **Azure Blob Storage** | Stores raw data in the `lcm-file-blobs` container: `metadata.csv` (product metadata) and individual `.xlsx` files (PSD curves per product). | +| **Azure Logic App** | Bridges SharePoint and Azure Storage. Copies PSD documents and translates the SharePoint product list into `metadata.csv`. Triggered by the API on user request. | +| **Application Insights** | Collects telemetry from both frontend (custom events) and backend (request logs) via OpenTelemetry. | +| **LCMLibrary SharePoint** | Primary data source. Product metadata and PSD Excel files are maintained here by domain users. | +| **Azure AD** | Authentication provider for both frontend and backend. Users must have appropriate roles to access the application. | + + +> For information about authentication flow and access management, see the [Authentication](authentication.md) runbook chapter. diff --git a/docs/operators/runbook/authentication.md b/docs/operators/runbook/authentication.md new file mode 100644 index 00000000..8b4375ba --- /dev/null +++ b/docs/operators/runbook/authentication.md @@ -0,0 +1,181 @@ +# Authentication + +This document describes the authentication and authorization flow used by the LCM Optimizer. + +## Auth Architecture Overview + +```mermaid +flowchart TB + subgraph Users["👤 Users"] + Browser["Web Browser"] + end + + subgraph Infrastructure["Infrastructure Layer"] + NGINX["NGINX Proxy
(port 8080)
auth_request /oauth2/auth"] + Redis["Redis Session Store
cookie_refresh: 15m
cookie_expire: 1h"] + end + + subgraph Frontend["Frontend Layer"] + Web["React/Vite Web App
Session expiry detection
Cross-tab re-auth support"] + OAuth2Proxy["OAuth2 Proxy
PKCE: S256
Allowed: equinor.com"] + end + + subgraph Backend["Backend Layer"] + API["Flask Backend
JWT: RS256
JWKS Cache: 24h"] + ABAC["ABAC Engine
Role-based permissions"] + end + + subgraph EntraID["Microsoft Entra ID
(Equinor Tenant)"] + JWKS["JWKS Endpoint
Token Signing Keys"] + + OAuthApp["lcm-oauth2-{env}
User Authentication"] + APIApp["lcm-api-{env}
Backend Identity
Exposes: /access scope"] + + subgraph Roles["App Roles"] + RoleReader["Default
Read/sync access"] + end + end + + subgraph CICD["CI/CD"] + GitHub["GitHub Actions
Federated Identity"] + KeyVault["Azure Key Vault
lcm-{env}-vault"] + end + + Browser -->|"1. Request"| NGINX + NGINX -->|"2. auth_request"| OAuth2Proxy + OAuth2Proxy <-->|"Session storage"| Redis + OAuth2Proxy -->|"3. OIDC Login
Scopes: openid profile
email offline_access
api/access"| OAuthApp + OAuthApp -->|"Requests permission"| APIApp + + NGINX -->|"4. Forward with headers
Authorization: Bearer id_token
X-Forwarded-Access-Token"| API + API -->|"5. Validate JWT"| JWKS + + GitHub -->|"Workload Identity Federation"| EntraID + KeyVault -->|"Secrets"| OAuth2Proxy + KeyVault -->|"Secrets"| API + + style EntraID fill:#0078d4,color:#fff + style Roles fill:#ffd700,color:#000 + style CICD fill:#238636,color:#fff +``` + +## BFF Authentication Pattern + +The BFF (Backend-for-Frontend) pattern places a server-side component between the browser and backend API to handle authentication. In this implementation: + +- **OAuth2-Proxy** manages authentication sessions and token handling +- **NGINX** acts as the entry point, enforcing auth via `auth_request` +- **Redis** stores encrypted session data +- **Frontend** uses cookie-based sessions (no tokens in JavaScript) + +```mermaid +flowchart LR + subgraph Browser + SPA["React SPA"] + end + + subgraph BFF["BFF Layer"] + NGINX["NGINX
:8080"] + OAuth2["OAuth2-Proxy
:8081"] + Redis["Redis
Session Store"] + end + + subgraph Backend + API["API Server
:5000"] + end + + subgraph IdP["Identity Provider"] + EntraID["Microsoft Entra ID"] + end + + SPA -->|"1. Request /api/*"| NGINX + NGINX -->|"2. auth_request"| OAuth2 + OAuth2 <-->|"Session lookup"| Redis + OAuth2 -->|"3. Validate/Refresh"| EntraID + NGINX -->|"4. Forward + tokens"| API + API -->|"5. Response"| NGINX + NGINX -->|"6. Response"| SPA +``` + +### Authentication Flow + +The following sequence diagram shows the step-by-step authentication flow when a user accesses the application: + +```mermaid +sequenceDiagram + participant Browser + participant NGINX + participant OAuth2-Proxy + participant Redis + participant EntraID as Microsoft Entra ID + participant API + + Browser->>NGINX: GET /api/data + NGINX->>OAuth2-Proxy: auth_request /oauth2/auth + OAuth2-Proxy->>Redis: Lookup session cookie + + alt No valid session + OAuth2-Proxy-->>NGINX: 401 Unauthorized + NGINX-->>Browser: Redirect to /oauth2/sign_in + Browser->>OAuth2-Proxy: GET /oauth2/sign_in + OAuth2-Proxy-->>Browser: Redirect to Entra ID + Browser->>EntraID: Authorization request (PKCE) + EntraID-->>Browser: Redirect with authorization code + Browser->>OAuth2-Proxy: GET /oauth2/callback?code=... + OAuth2-Proxy->>EntraID: Exchange code for tokens + EntraID-->>OAuth2-Proxy: Access + ID + Refresh tokens + OAuth2-Proxy->>Redis: Store encrypted session + OAuth2-Proxy-->>Browser: Set cookie, redirect to original URL + end + + alt Valid session + OAuth2-Proxy-->>NGINX: 200 OK + token headers + NGINX->>API: Forward request with
Authorization: Bearer id_token
X-Forwarded-Access-Token: access_token + API->>EntraID: Validate JWT via JWKS + API-->>NGINX: Response + NGINX-->>Browser: Response + end +``` + +## Security Benefits + +| Feature | Implementation | Benefit | +|-----------------------------|----------------------------------------|------------------------------------------| +| **No tokens in browser JS** | OAuth2-Proxy stores tokens server-side | Prevents XSS token theft | +| **HttpOnly cookies** | `cookie_httponly = true` | JavaScript cannot access session cookie | +| **Secure cookies** | `cookie_secure = true` | Cookies only sent over HTTPS | +| **SameSite cookies** | `cookie_samesite = "lax"` | CSRF protection | +| **Encrypted sessions** | `OAUTH2_PROXY_COOKIE_SECRET` | Session data encrypted at rest in Redis | +| **Automatic token refresh** | `cookie_refresh = "15m"` | Tokens refreshed before expiry | +| **PKCE** | `code_challenge_method: S256` | Prevents authorization code interception | +| **API 401 responses** | `api_routes = ["^/api/.*"]` | APIs return 401, not redirect | +| **JWT validation** | RS256 + JWKS | Cryptographic token verification | +| **24h JWKS cache** | `TTLCache(ttl=86400)` | Performance with security | + +## Azure AD App Registration + +The application has a single App Registration in Azure AD: + +| Property | Value | +|----------|-------| +| **App ID (Client ID)** | `1dbc1e96-268d-41ad-894a-92a9fb85f954` | +| **Tenant ID** | `3aa4a235-b6e2-48d5-9195-7fcf05b459b0` | +| **API Identifier URI** | `api://lost-circulation-material-api` | + +### App Registration links + +- [App Registration in Azure Portal](https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Overview/appId/1dbc1e96-268d-41ad-894a-92a9fb85f954/isMSAApp~/false) +- [Enterprise Application](https://portal.azure.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e8f33fc2-ed9d-42ba-a8e1-44951d111671/appId/1dbc1e96-268d-41ad-894a-92a9fb85f954) + + +### Managing user access + +To manage who can access the application, you need to be added as an owner to the [Enterprise Application](https://portal.azure.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e8f33fc2-ed9d-42ba-a8e1-44951d111671/appId/1dbc1e96-268d-41ad-894a-92a9fb85f954). + +## Permissions required + +| Action | Requirement | +|--------|-------------| +| Managing user access | Owner of the Enterprise Application | +| Managing App Registration | Owner of the Azure App Registration | +| Managing Radix | Member of the `Radix Platform Users` groups (via AccessIT) + member of the [Team Hermes Radix Admin](https://portal.azure.com/#view/Microsoft_AAD_IAM/GroupDetailsMenuBlade/~/Overview/groupId/13b319d8-ee25-4b6b-97db-74bad07d2057) group | diff --git a/docs/operators/runbook/configuration.md b/docs/operators/runbook/configuration.md new file mode 100644 index 00000000..32c0719c --- /dev/null +++ b/docs/operators/runbook/configuration.md @@ -0,0 +1,108 @@ +# Configuration + +This document describes the system resources and configuration used by the LCM Optimizer. + +## Azure resources + +All Azure resources are located under the [S118 subscription](https://portal.azure.com/#@StatoilSRM.onmicrosoft.com/resource/subscriptions/0a78ee8b-9e26-4088-9f6d-8de5fc5cd0ae/overview). + +### Storage Account (`lcmdevstorage`) + +#### Blob container + +- **Container name**: `lcm-file-blobs` +- **Contents**: + - `metadata.csv` — Product metadata exported from the SharePoint list + - Individual `.xlsx` files — Particle Size Distribution (PSD) data per product + +#### Table Storage + +- **Table name**: `products` +- **Purpose**: Stores processed product data used by the API. This table is rebuilt from the blob data whenever the "Synchronize with SharePoint" function is called. + +### Application Insights + +Provisioned via Bicep (IaC) in `IaC/main.bicep`. + +| Resource | Description | +|----------|-------------| +| **Log Analytics Workspace** | `lcm--logWorkspace` — Backend log aggregation | +| **Application Insights** | `lcm--logs` — Telemetry for both frontend and backend | + + +#### Logging details + +- **Frontend**: Tracks loading of `Main.tsx` via custom events. Query `customEvents` in Application Insights. +- **Backend**: Every request is logged via OpenTelemetry instrumentation. Query `requests` in Application Insights. + +### Logic App +An _Azure Logic app_ is used to solve the problem of syncing files from SharePoint to blobs in the StorageAccount. This is not done directly by the API as there was some lacking permission features in the MS Graph API at the time. +It also translates a SharePoint List (Product) into a .csv file ("metadata.csv") that is loaded to blob storage. + +- **Resource**: `TransferDocsToBlob` +- **Purpose**: Synchronizes files and metadata from SharePoint to Azure Blob Storage +- **Trigger**: HTTP (called by the API when the user clicks "Synchronize with SharePoint") + +The Logic App: + +1. Copies PSD `.xlsx` documents from SharePoint to the `lcm-file-blobs` blob container +2. Translates the SharePoint "Product" list into `metadata.csv` and uploads it to the same container + +#### API Connections + +The Logic App uses two API connections: + +| Connection | Purpose | Authentication | +|------------|---------|----------------| +| `sharepointonline` | Access to the SharePoint site | Equinor credentials (function user `f_lcm_blend@statoil.net`) | +| `azureblob` | Access to the Storage Account | Storage Account access key | + +> **Troubleshooting**: If the Logic App returns "unauthorized" errors, the API connection tokens may have expired. See the [Reauthorizing Logic App connections](#reauthorizing-logic-app-connections) section below. + + +### SharePoint +The SharePoint site is the main data provider for the application. Product metadata and product Particle Size Distribution (PSD) data is stored and updated here. + +- **Site**: `https://statoilsrm.sharepoint.com/sites/LCMlibrary` +- **Purpose**: Primary data source for product information + +> **Important**: For the link between product metadata and PSD data to work, the product name in the SharePoint "Product" list must exactly match the corresponding `.xlsx` filename. + + +### Secrets (Radix) + +The following secrets must be configured in the Radix console: + +| Secret | Used by | Description | +|--------|---------|-------------| +| `TABLE_KEY` | API | Azure Table Storage access key | +| `APPINSIGHTS_CON_STRING` | API, Web (build) | Application Insights connection string | + + +## Updating data + +To synchronize product data between SharePoint and Azure: + +1. Open the LCM web application. +2. Click the **"Synchronize with SharePoint"** button. +3. This triggers the Logic App, which copies data from SharePoint to Azure Storage. +4. The API rebuilds the `products` table from the new blob data. + +### Adding a new product + +1. Go to [SharePoint](https://statoilsrm.sharepoint.com/sites/LCMlibrary) → **Documents**. +2. Open the folder for the supplier → open the **PSD** folder. +3. Click **"+ New"** to create a new LCM PSD Excel Sheet. +4. Go back to [SharePoint](https://statoilsrm.sharepoint.com/sites/LCMlibrary) → **Products summary**. +5. Click **"+ New"** and add metadata for the product. + > **Important**: The product name must exactly match the Excel sheet filename. +6. Open the LCM web application and click **"Synchronize with SharePoint"**. + +## Reauthorizing Logic App connections + +If the Logic App returns "unauthorized" errors, the API connection tokens have likely expired. To fix: + +1. Go to the `TransferDocsToBlob` resource in the Azure Portal. +2. Go to **API connections**. +3. Click on **`sharepointonline`** → **Edit API connection** → **Authorize**. Log in with Equinor credentials. +4. Click on **`azureblob`** → **Edit API connection** → **Authorize**. Paste the Azure Storage Account access key (found in `lcmdevstorage` → **Access keys**). diff --git a/docs/operators/runbook/deployment.md b/docs/operators/runbook/deployment.md new file mode 100644 index 00000000..3edc31ac --- /dev/null +++ b/docs/operators/runbook/deployment.md @@ -0,0 +1,45 @@ +# Deployment + +This document describes how the LCM Optimizer is deployed and how to release new versions. + +## Deployment platform + +The application is deployed on [Omnia Radix](https://www.radix.equinor.com), Equinor's PaaS platform built on Kubernetes. Radix handles container builds, deployments, scaling, TLS certificates, and DNS management. + +- **Radix Console**: [lost-circulation-material](https://console.radix.equinor.com/applications/lost-circulation-material) +- **Radix Config**: `radixconfig.yaml` in the repository root + +### Branch-to-environment mapping + +| Environment | Deployment Process | URL | +|-------------|-----------------|-----| +| `test` | Automatically reflects the latest changes in `master` branch | `https://proxy-lost-circulation-material-test.radix.equinor.com` | +| `prod` | Promoted manually from Test via the Radix web console. | `https://lost-circulation-material.app.radix.equinor.com` | + + +## Secrets + +The following secrets must be configured per environment in the Radix console: + +| Secret | Component | Description | +|--------|-----------|-------------| +| `TABLE_KEY` | API | Azure Table Storage access key | +| `APPINSIGHTS_CON_STRING` | API | Application Insights connection string | + + +## Certificates + +No application-managed certificates are currently in use. TLS is handled by the Radix platform. + +## Monitoring deployments + +- **Radix Console**: View build logs, deployment status, and replica health +- **Application Insights**: Monitor request performance, errors, and custom events +- **Radix logs**: View container stdout/stderr logs in real time + +## Access requirements + +To deploy and manage the application in Radix, you need: + +1. `Radix Platform Users` roles — apply via [AccessIT](https://accessit.equinor.com) +2. Membership in the [Team Hermes Radix Admin](https://portal.azure.com/#view/Microsoft_AAD_IAM/GroupDetailsMenuBlade/~/Overview/groupId/13b319d8-ee25-4b6b-97db-74bad07d2057) group diff --git a/docs/operators/runbook/index.md b/docs/operators/runbook/index.md new file mode 100644 index 00000000..3e3e0f2b --- /dev/null +++ b/docs/operators/runbook/index.md @@ -0,0 +1,80 @@ +# Overview + +_This document provides operational and administrative details for managing the LCM application, including deployments, updates, and incident responses. The primary audience is personnel responsible for managing and operating the system._ + +| Topic | Description | +|---------------------------------------|----------------------------------------------------------------| +| [Architecture](architecture.md) | Overview of system architecture, components, and interactions. | +| [Authentication](authentication.md) | Details on how authentication and authorization are implemented. | +| [Configuration](configuration.md) | Details on system configuration, including secrets and settings. | +| [Deployment](deployment.md) | Instructions for deploying updates and managing releases. | +| [Operations](operations.md) | Change management, updates and backups | +| [Security](security.md) | Security considerations, including vulnerability management. | + +### Permissions required + +* **For Managing User Access** + * To manage who can access the application, you need to be added as an owner to the [Enterprise Application][lcm-enterprise-app]. +* **For Managing Radix** + * To access the Radix console + * Apply for the `Radix Platform Users` and `Radix Playground Users` through https://accessit.equinor.com + * Added to the [Team Hermes Radix Admin][radix-admin-group] group that controls who can administrate the Radix application. + * To change the `radixconfig.yaml` file + * Added to the [GitHub repository][github-repository] +* **For Managing App registration** + * Apply for the `Application Developer with Admin key` role through https://accessit.equinor.com + * Need to be a certified developer to get this role. + * Added as owners to the Azure [App Registration][app-registration] +* **For running deployments to Azure using Bicep** + * Your `az_` account must have these roles (or greater) for the relevant subscription and resource group: + * [Automation Contributor][automation-contributor] + * [Managed Identity Contributor][managed-identity-contributor] (only when creating a Managed Identity with a Federated Credentials) + * [Contributor][contributor] (only applicable when bootstrapping the common resource group) + * [Application Developer][accessit-application-developer] + * The `az_` account also needs to be a member of the group [AZAPPL S118 - Owner][lcm-owner-group]. + * It does not need to be an owner of the group, only a member. + + +### Competence required + +* [Radix](https://www.radix.equinor.com) +* [GitHub Actions](https://docs.github.com/en/actions) +* [Azure](https://learn.microsoft.com/en-us/azure/) +* [npm](https://docs.npmjs.com/) +* [Docker](https://docs.docker.com/) +* [React](https://react.dev/) +* [Oauth2](https://oauth.net/2/) +* [Python](https://www.python.org/) +* [Pre-commit](https://pre-commit.com/) +* [Git](https://git-scm.com/) + + +## Platforms + +> _Quick overview of platforms used._ + +- [ ] [DRM](https://drm.equinor.com/) + - [ ] [Omnia Classic](https://docs.omnia.equinor.com/products/Service-Offerings/#omnia-classic) + - [x] [Omnia Standalone](https://docs.omnia.equinor.com/products/Service-Offerings/#omnia-standalone) + - [Azure subscription][azure-subscription] - All Azure resources are located under this subscription. + - [x] [Omnia Radix](https://www.radix.equinor.com) + - [Radix Console][radix-application-console] - The console for the application registered in Radix. + +## Communication channels + +> _Communication channels related to the application's operation._ + +- [Slack: Project Channel][slack-project-channel] + +[azure-subscription]: https://portal.azure.com/#@StatoilSRM.onmicrosoft.com/resource/subscriptions/0a78ee8b-9e26-4088-9f6d-8de5fc5cd0ae/overview +[lcm-radix-console]: https://console.radix.equinor.com/applications/lost-circulation-material +[radix-admin-group]: https://portal.azure.com/#view/Microsoft_AAD_IAM/GroupDetailsMenuBlade/~/Overview/groupId/13b319d8-ee25-4b6b-97db-74bad07d2057 +[github-repository]: https://github.com/equinor/lost-circulation-material +[slack-project-channel]: https://equinor.enterprise.slack.com/archives/C0150KM2VD0 +[app-registration]: https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Overview/appId/1dbc1e96-268d-41ad-894a-92a9fb85f954/isMSAApp~/false +[lcm-owner-group]: https://portal.azure.com/#view/Microsoft_AAD_IAM/GroupDetailsMenuBlade/~/Overview/groupId/c2e76a65-53d6-4605-a54f-ac0e55920344 +[lcm-enterprise-app]: https://portal.azure.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e8f33fc2-ed9d-42ba-a8e1-44951d111671/appId/1dbc1e96-268d-41ad-894a-92a9fb85f954 +[accessit-application-developer]: https://accessit.equinor.com/Search/Search?term=Application+Developer+with+Admin+key+%28AAD%29+%28MICROSOFT+ENTRA+ID%29 +[automation-contributor]: https://portal.azure.com/?feature.msaljs=true#view/Microsoft_Azure_AD/RolePermissionsLandingBlade/allowRoleSelection~/false/priorityRoles~/%5B%5D/roleId/%2Fsubscriptions%2F467ce2f8-e948-4df0-b2ba-8b9b285dd237%2Fproviders%2FMicrosoft.Authorization%2FroleDefinitions%2Ff353d9bd-d4a6-484e-a77a-8050b599b867/scope/%2Fsubscriptions%2F467ce2f8-e948-4df0-b2ba-8b9b285dd237/showLinks~/false +[managed-identity-contributor]: https://portal.azure.com/#view/Microsoft_Azure_AD/RolePermissionsLandingBlade/allowRoleSelection~/false/priorityRoles~/%5B%5D/roleId/%2Fsubscriptions%2F467ce2f8-e948-4df0-b2ba-8b9b285dd237%2Fproviders%2FMicrosoft.Authorization%2FroleDefinitions%2Fe40ec5ca-96e0-45a2-b4ff-59039f2c2b59/scope/%2Fsubscriptions%2F467ce2f8-e948-4df0-b2ba-8b9b285dd237/showLinks~/false +[contributor]: https://portal.azure.com/#view/Microsoft_Azure_AD/RolePermissionsLandingBlade/allowRoleSelection~/false/priorityRoles~/%5B%5D/roleId/%2Fsubscriptions%2F467ce2f8-e948-4df0-b2ba-8b9b285dd237%2Fproviders%2FMicrosoft.Authorization%2FroleDefinitions%2Fb24988ac-6180-42a0-ab88-20f7382dd24c/scope/%2Fsubscriptions%2F467ce2f8-e948-4df0-b2ba-8b9b285dd237/showLinks~/false diff --git a/docs/operators/runbook/operations.md b/docs/operators/runbook/operations.md new file mode 100644 index 00000000..d86c8db2 --- /dev/null +++ b/docs/operators/runbook/operations.md @@ -0,0 +1,32 @@ +# Operations + +> _Higher-level tasks associated with managing the system, and routine activities required to keep the system running smoothly._ + +## Change Management + +> _Describe how changes to the system are managed, including approval workflows._ + +Changes are decided, designed, and developed by the team in agreement with the Business Solution Owner (BSO). After development and testing, changes are demonstrated to the BSO and deployed to production. + +## Access Management + +> _Adding or removing users. Managing permissions and access controls._ + +Any member within the All Equinor Users group has access to the application by default. + +## Functional updates + +> _Describe how functional updates are planned, developed, tested, and deployed._ + +Functional updates will usually happen when we decide to add or upgrade features and improvements from the business. + +## Capacity management + +> _Describe how system capacity is monitored and managed._ + +System capacity is monitored and managed using Radix built-in tools. + +## Backup and restore + +> _Provide overview of backup schedules, restoration steps, and responsible personnel._ +Backups of Azure resources are handled by Azure's built-in backup solutions. For Azure Table Storage, point-in-time restore is enabled. For Azure Blob Storage, soft delete is enabled to protect against accidental deletions in addition to SharePoint being the source of truth for the data. In case of a need to restore data, the Azure portal can be used to access backup and restore options for the relevant resources. diff --git a/docs/operators/runbook/security.md b/docs/operators/runbook/security.md new file mode 100644 index 00000000..5eb508c7 --- /dev/null +++ b/docs/operators/runbook/security.md @@ -0,0 +1,36 @@ +# Security Management + +## Security Incidents + +> _Describe how information security incidents are handled._ + +Security Incidents should be reported at [Equinor's Computer Security Incident Response Team](https://www.equinor.com/about-us/csirt) as soon as identified. + +## Security Checks + +> _Security checks done every quarter._ + +| When | Who | Status | +|----------|--------------------|--------| +| Q1 xxxx | username, username | OK | + +Tasks to perform: + +* Update passwords and certificates where applicable (Key Vault secrets). +* Review users and admin access in: + * App registration and Enterprise application (roles and assignments). + * Azure subscription role assignments (Owners/Contributors). + * GitHub repository teams and collaborators. + * Radix `Team Hermes Radix Admin` group membership. + +## Monitoring Vulnerabilities + +> _Identifying, review and apply security patches._ + +We use [GitHub Advanced Security][ghas] for: + +* **Dependency Scanning (SCA)**: Detects and updates vulnerable third-party dependencies via the Dependency Graph. +* **Code Scanning (SAST)**: Analyzes source code for security and quality issues using CodeQL before deployment. +* **Secret Scanning**: Alerts on exposed secrets in the codebase to prevent leaks. + +[ghas]: https://docs.github.com/en/code-security/github-advanced-security \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 00000000..e65c3da9 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,32 @@ +site_name: Lost Circulation Material (LCM) Docs +repo_url: https://github.com/equinor/lcm +site_description: Documentation for the Lost Circulation Material (LCM) application +site_url: https://lost-circulation-material.app.radix.equinor.com +docs_dir: docs +theme: + name: material +plugins: + - techdocs-core +markdown_extensions: + - admonition + - codehilite + - pymdownx.emoji: + emoji_index: !!python/name:material.extensions.emoji.twemoji + emoji_generator: !!python/name:material.extensions.emoji.to_svg + - pymdownx.details +nav: + - Home: index.md + - LCM Developers: + - Overview: developers/guide/index.md + - Setup: developers/guide/setup.md + - Running: developers/guide/running.md + - Testing: developers/guide/testing.md + - Upgrading: developers/guide/upgrading.md + - LCM Operators: + - Overview: operators/runbook/index.md + - Authentication: operators/runbook/authentication.md + - Architecture: operators/runbook/architecture.md + - Configuration: operators/runbook/configuration.md + - Deployment: operators/runbook/deployment.md + - Operations: operators/runbook/operations.md + - Security: operators/runbook/security.md diff --git a/nginx/Dockerfile b/nginx/Dockerfile index c84bbd1a..e88f205f 100644 --- a/nginx/Dockerfile +++ b/nginx/Dockerfile @@ -1,4 +1,4 @@ -FROM nginx:1.27.2-alpine AS server +FROM nginx:1.29.5-alpine AS server RUN apk upgrade --update-cache diff --git a/nginx/default.nginx b/nginx/default.nginx index df28aaeb..b62f3324 100644 --- a/nginx/default.nginx +++ b/nginx/default.nginx @@ -13,43 +13,102 @@ http { fastcgi_temp_path /tmp/nginx/fastcgi_temp; uwsgi_temp_path /tmp/nginx/uwsgi_temp; scgi_temp_path /tmp/nginx/scgi_temp; - + + # These parameters fix too 'large headers' from Entra Tokens. + proxy_buffer_size 128k; # Adjust as needed + proxy_buffers 4 256k; # Adjust as needed + proxy_busy_buffers_size 256k; # Adjust as needed server { listen 8080; server_name localhost; - client_max_body_size 2G; + client_max_body_size 0; # disable upload limit as it is handled by Radix access_log /dev/stdout combined; error_log /dev/stdout; + location /oauth2 { + proxy_pass http://oauth2-proxy:8081; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Auth-Request-Redirect $request_uri; + proxy_set_header X-Scheme $scheme; + } + + location = /oauth2/auth { + proxy_pass http://oauth2-proxy:8081; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Uri $request_uri; + proxy_set_header X-Scheme $scheme; + # nginx auth_request includes headers but not body + proxy_set_header Content-Length ""; + proxy_pass_request_body off; + } + + location /api { proxy_pass http://api:5000/api; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection upgrade; - proxy_set_header Host $http_host; - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-For $remote_addr; - proxy_set_header X-Forwarded-Port $server_port; - proxy_set_header X-Request-Start $msec; - proxy_read_timeout 180; + proxy_http_version 1.1; + add_header Last-Modified $date_gmt; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Port $server_port; + proxy_set_header Host $host; + proxy_set_header X-Request-Start $msec; + + auth_request /oauth2/auth; + + # if you enabled --pass-access-token, this will pass the token to the backend + auth_request_set $token $upstream_http_authorization; + proxy_set_header Authorization $token; + + auth_request_set $access_token $upstream_http_x_auth_request_access_token; + proxy_set_header X-Forwarded-Access-Token $access_token; + + proxy_read_timeout 180; + error_page 401 = @api_unauthorized; + } + + location @api_unauthorized { + return 401; } + location / { - proxy_read_timeout 180; proxy_pass http://web:3000/; # Passthrough for websocket - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_set_header Host $host; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_http_version 1.1; + add_header Last-Modified $date_gmt; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Port $server_port; + proxy_set_header X-Request-Start $msec; + proxy_set_header Upgrade $http_upgrade; + proxy_read_timeout 180; + auth_request /oauth2/auth; + + # if you enabled --pass-access-token, this will pass the token to the backend + auth_request_set $token $upstream_http_authorization; + proxy_set_header Authorization $token; + auth_request_set $access_token $upstream_http_x_auth_request_access_token; + proxy_set_header X-Forwarded-Access-Token $access_token; + # security headers - add_header X-XSS-Protection "1; mode=block" always; add_header X-Content-Type-Options "nosniff" always; - add_header Referrer-Policy "no-referrer-when-downgrade" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Permissions-Policy "interest-cohort=()" always; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; + add_header X-Frame-Options "DENY" always; + error_page 401 = /oauth2/sign_in?rd=$scheme://$host$request_uri; } } } diff --git a/oauth2/Dockerfile b/oauth2/Dockerfile new file mode 100644 index 00000000..42a9058f --- /dev/null +++ b/oauth2/Dockerfile @@ -0,0 +1,6 @@ +FROM dhi.io/oauth2-proxy:7.14.2-debian13 + +COPY oauth2-proxy.toml /etc/ +COPY oauth2-proxy.yaml /etc/ + +CMD ["--config", "/etc/oauth2-proxy.toml", "--alpha-config", "/etc/oauth2-proxy.yaml"] diff --git a/oauth2/oauth2-proxy.toml b/oauth2/oauth2-proxy.toml new file mode 100644 index 00000000..a9199245 --- /dev/null +++ b/oauth2/oauth2-proxy.toml @@ -0,0 +1,32 @@ +# Below are the configurations that are not (yet) supported in the alpha config + +# Provider information +## These are required +email_domains = [ + "equinor.com", + "statoilsrm.onmicrosoft.com", +] + +## These are _technically_ not required, but we need to nonetheless +reverse_proxy = true + +## Automatic redirect +skip_provider_button = true + +# Cookie settings +cookie_samesite = "lax" +cookie_secure = true +cookie_httponly = true +cookie_refresh = "15m" +cookie_expire = "1h" +cookie_csrf_per_request = true +cookie_csrf_per_request_limit = 20 + +## Cookie storage +session_store_type = "redis" +redis_connection_url = "redis://redis:6379" + +## mark paths as API routes to get HTTP Status code 401 instead of redirect to login page +api_routes = [ + "^/api/.*" +] diff --git a/oauth2/oauth2-proxy.yaml b/oauth2/oauth2-proxy.yaml new file mode 100644 index 00000000..62e7feed --- /dev/null +++ b/oauth2/oauth2-proxy.yaml @@ -0,0 +1,43 @@ +injectResponseHeaders: + - name: X-Auth-Request-Access-Token + values: + - claimSource: + claim: access_token + - name: Authorization + values: + - claimSource: + claim: id_token + prefix: "Bearer " + +providers: + - provider: oidc + id: Microsoft Entra ID + clientID: ${OAUTH_CLIENT_ID} + clientSecret: ${CLIENT_SECRET} + clientSecretFile: ${CLIENT_SECRET_FILE} + scope: openid profile email + oidcConfig: + emailClaim: email + audienceClaims: + - aud + insecureAllowUnverifiedEmail: true + issuerURL: "https://login.microsoftonline.com/3aa4a235-b6e2-48d5-9195-7fcf05b459b0/v2.0" + # By default, oauth2-proxy discovers the userinfo URL, and then fails to log + # in as it can't fetch the groups list from there. We don't care about AAD + # group memberships, so instead we must disable discovery and manually + # configure the other URLs that would normally be discovered but leave the + # profileURL blank. This way it doesn't attempt to fetch groups at all. + skipDiscovery: true + jwksURL: "https://login.microsoftonline.com/3aa4a235-b6e2-48d5-9195-7fcf05b459b0/discovery/v2.0/keys" + loginURL: "https://login.microsoftonline.com/3aa4a235-b6e2-48d5-9195-7fcf05b459b0/oauth2/v2.0/authorize" + redeemURL: "https://login.microsoftonline.com/3aa4a235-b6e2-48d5-9195-7fcf05b459b0/oauth2/v2.0/token" + code_challenge_method: S256 + +server: + BindAddress: 0.0.0.0:8081 + +upstreamConfig: + upstreams: + - id: nginx + path: / + uri: http://nginx:8080/ diff --git a/radixconfig.yaml b/radixconfig.yaml index d4d93378..d3f77a84 100644 --- a/radixconfig.yaml +++ b/radixconfig.yaml @@ -3,6 +3,8 @@ kind: RadixApplication metadata: name: lost-circulation-material spec: + build: + useBuildKit: false environments: - name: prod build: @@ -11,6 +13,18 @@ spec: build: from: master components: + - name: redis + src: ./redis + secrets: + - REDIS_PASSWORD + - name: oauth2-proxy + src: ./oauth2 + environment: + OAUTH_CLIENT_ID: "1dbc1e96-268d-41ad-894a-92a9fb85f954" + secrets: + - OAUTH2_PROXY_COOKIE_SECRET + - OAUTH2_PROXY_REDIS_PASSWORD + - CLIENT_SECRET - name: web src: ./web ports: @@ -20,10 +34,10 @@ spec: src: ./api resources: requests: - memory: '800Mi' - cpu: '100m' + memory: "800Mi" + cpu: "100m" limits: - cpu: '4000m' + cpu: "4000m" environmentConfig: - environment: prod variables: @@ -36,7 +50,7 @@ spec: cpu: value: 85 - name: memory - cpu: + memory: value: 75 - environment: test variables: @@ -49,16 +63,16 @@ spec: cpu: value: 85 - name: memory - cpu: + memory: value: 75 ports: - name: flask port: 5000 - publicPort: flask secrets: - TABLE_KEY - - - name: proxy + - APPINSIGHTS_CON_STRING + - SYNC_BLOBS_APP_URL + - name: nginx src: ./nginx/ ports: - name: nginx @@ -67,4 +81,4 @@ spec: dnsAppAlias: environment: prod - component: proxy + component: nginx diff --git a/redis/.dockerignore b/redis/.dockerignore new file mode 100644 index 00000000..bb633c12 --- /dev/null +++ b/redis/.dockerignore @@ -0,0 +1,2 @@ +* +!rootfs/ diff --git a/redis/Dockerfile b/redis/Dockerfile new file mode 100644 index 00000000..f59621ba --- /dev/null +++ b/redis/Dockerfile @@ -0,0 +1,9 @@ +FROM dhi.io/redis:7.4.7-debian13-compat +# Redis 8.4 (and later) are not available on DHI yet, so we use the last open source release + +ENV USER="nonroot" + +COPY --chown="$USER:$USER" rootfs / + +ENTRYPOINT ["tini", "--", "entrypoint.sh"] +HEALTHCHECK --start-interval=0.5s --start-period=5s CMD ["healthcheck.sh"] diff --git a/redis/rootfs/usr/local/sbin/entrypoint.sh b/redis/rootfs/usr/local/sbin/entrypoint.sh new file mode 100644 index 00000000..5c2f0863 --- /dev/null +++ b/redis/rootfs/usr/local/sbin/entrypoint.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env sh +set -eu + +if [ "${TRACE:-}" = "1" ]; then + set -x +fi + +if [ -z "${REDIS_PASSWORD:-}" ]; then + if [ -z "${REDIS_PASSWORD_FILE:-}" ]; then + echo "REDIS_PASSWORD or REDIS_PASSWORD_FILE must be set" >/dev/stderr + exit 1 + else + REDIS_PASSWORD="$(cat "$REDIS_PASSWORD_FILE")" + export REDIS_PASSWORD + fi +fi + +if test -n "${1:-}" && [ "$1" != "redis-server" ]; then + exec "$@" +fi + +[ "${1:-}" = "redis-server" ] && shift # Remove duplicate redis-server argument if present +exec redis-server --requirepass "$REDIS_PASSWORD" --save "" "$@" diff --git a/redis/rootfs/usr/local/sbin/healthcheck.sh b/redis/rootfs/usr/local/sbin/healthcheck.sh new file mode 100644 index 00000000..866ac461 --- /dev/null +++ b/redis/rootfs/usr/local/sbin/healthcheck.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env sh +set -eu + +if [ -z "${REDIS_PASSWORD:-}" ] && [ -n "${REDIS_PASSWORD_FILE:-}" ]; then + REDIS_PASSWORD="$(cat "$REDIS_PASSWORD_FILE")" +fi + +REDISCLI_AUTH="${REDIS_PASSWORD:-}" redis-cli ping diff --git a/runbook.md b/runbook.md deleted file mode 100644 index e699f520..00000000 --- a/runbook.md +++ /dev/null @@ -1,182 +0,0 @@ -# LCM Runbook - -This document covers most operational information about the LCM Web app and API. - -## Links - -- [Github repo](https://github.com/equinor/lcm) -- [GitHub Project](https://github.com/orgs/equinor/projects/641) -- [Architecture Contract](https://github.com/equinor/architecturecontract/blob/master/contracts/LCMLibrary.md) -- [IT Application (Configuration Item)](https://equinor.service-now.com/selfservice?id=form&table=cmdb_ci_business_app&sys_id=156e5bbd93da29d0eaf1f4527cba10e4) - -## Prerequisites - -> _List of all necessary permissions, or knowledge required to perform the tasks described in this runbook._ - -
- Permissions required - -* **For Managing User Access** - * Added as owner to the [Enterprise registration](https://portal.azure.com/#view/Microsoft_AAD_IAM/ManagedAppMenuBlade/~/Overview/objectId/e8f33fc2-ed9d-42ba-a8e1-44951d111671/appId/1dbc1e96-268d-41ad-894a-92a9fb85f954). -* **For Managing Radix** - * To access the Radix console - * Apply for the `Radix Platform Users` and `Radix Playground Users` through https://accessit.equinor.com - * Added to the [Team Hermes Radix Admin](https://portal.azure.com/#view/Microsoft_AAD_IAM/GroupDetailsMenuBlade/~/Overview/groupId/13b319d8-ee25-4b6b-97db-74bad07d2057) group that controls who can administrate the Radix application. -* **For Managing App registration** - * Added as owners to the Azure [App registration](https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Overview/appId/1dbc1e96-268d-41ad-894a-92a9fb85f954/isMSAApp~/false) - -
- -
- Competence required - -* [Radix](https://www.radix.equinor.com) -* [GitHub Actions](https://docs.github.com/en/actions) -* [Azure](https://learn.microsoft.com/en-us/azure/) -* [npm](https://docs.npmjs.com/) -* [Docker](https://docs.docker.com/) -* [React](https://react.dev/) -* [Oauth2](https://oauth.net/2/) -* [Python](https://www.python.org/) -* [Pre-commit](https://pre-commit.com/) -* [Git](https://git-scm.com/) - -
- -## Architecture - -![Diagram](doc/diagram.drawio.svg) - -### Omnia Radix - -The Web frontend and the API are deployed to Equinors Omnia Radix PaaS platform. This has its own documentation available at [https://www.radix.equinor.com](https://www.radix.equinor.com). The configuration for our radix app is in [radixconfig.yaml](./radixconfig.yaml). -Two different environments in Radix are used: one for test (deploys from branch "master") and one for production (deploy from branch "prod"). Deploys will happen automatically when pushing to these branches. - -#### TLS and DNS - -The radix configuration handles management of TLS certificates as well as DNS entries. The main hostname is `https://lost-circulation-material.app.radix.equinor.com`. This serves the Single Page Application. The API is available under the `/api` location. - -### SharePoint - -The SharePoint site `https://statoilsrm.sharepoint.com/sites/LCMlibrary` is the main data provider for the application. Product metadata and product Particle Size Distribution (PSD) data is stored and updated here. -For the link between product data and product Particle Size Distribution (PSD) to work, the name of the product in the "Product"-list, should match the PSD.xlsx-filename. - -## Resources - -> _List of all resources used by the application, including servers, databases, and cloud services._ - -
- Radix - -**Hosted applications** - -| Name | Description | -|--------------------------------------------------|--------------------------------------| -| [Radix Application](https://console.radix.equinor.com/applications/lost-circulation-material) | The application registered in Radix. | - -
- -
- Azure - -**Subscriptions** - -| Subscription | Description Group | -|------------------------------------------|----------------------------------------------------------| -| [Azure subscription](https://portal.azure.com/#@StatoilSRM.onmicrosoft.com/resource/subscriptions/0a78ee8b-9e26-4088-9f6d-8de5fc5cd0ae/overview) | All Azure resources are located under this subscription. | - -**App registrations** - -| Name | Description | -|---------------------------------------|-------------------------------------------------------------------| -| [App registration](https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Overview/appId/1dbc1e96-268d-41ad-894a-92a9fb85f954/isMSAApp~/false) | The application object registered in Azure for this application. | - -To make sure that the app registration are compliant: -* Add additional owner (to the Enterprise Application) -* Go to the `Branding & Properties` section and update the `Service Management Reference` to contain the App ID of the configuration item. - -_In order for the application to be able to authenticate users, you need an Application Registration in Azure AD that can sign in users and issue tokens._ - -
- -
- Secrets, Certificates and Keys - -> _Overview of all secrets and certificates used in the application._ - -**Application secrets** - - -| Name | Description | Used by | Obtained how | -|-----|-------------|---------|-------| -| TABLE_KEY | For the API to create and read Particle Distribution Curves stored in Azure Table Storage | API | "Access keys" in the Storage Account pane in Azure | - -
- -### StorageAccount - -#### Blob container - -One container called `lcm-file-blobs` -The SharePoint metadata list is stored here as "metadata.csv" as well as all the PSD .xlsx-documents for each product. - -#### Tables - -One table called `products` -This table is recreated by the API from the blobs whenever the "Synchronize with SharePoint" function is called. - -### Logic app - -An _Azure Logic app_ is used to solve the problem of syncing files from SharePoint to blobs in the StorageAccount. This is not done directly by the API as there was some lacking permission features in the MS Graph API at the time. -It also translates a SharePoint List (Product) into a .csv file ("metadata.csv") that is loaded to blob storage. - -Note: The access tokens used by the logic app can expire. If an "unauthorized error" occurs in the logic app, it can be fixed by: -1) Go to the TransferDocsToBlob resource in Azure. -2) Go to API connection. -3) Click on "sharepointonline" and click on edit API connection and "authorize". This will open a prompt where you have to log in with Equinor credentials. -4) Go back to the API connection list in the TransferDocsToBlob logic app and click on "azureblob" and "edit api connection". Under authorize, paste in the azure storage account access key (can be found inside the lcmdevstorage resource under the access keys tab). - -### API Connection - -Used to give the Logic app access to SharePoint and the StorageAccount. -These are easiest created by the Logic app designer in the Azure portal. -The function user `f_lcm_blend@statoil.net` is used for the SharePoint connection. - - -## Updating data -To synchronize data between Sharepoint and Azure, the user have to open the LCM web application and click the "Synchronize with Sharepoint" button. This will trigger the logic app to copy data from Sharepoint to Azure. - -To add a new product, the user must: -1) Go to [Sharepoint](https://statoilsrm.sharepoint.com/sites/LCMlibrary). -2) Click on "Documents". -3) Open the folder for a given supplier and click on the PSD folder. Here you can create a new LCM PSD Excel Sheet by clicking on the "+ New" button. -4) Go back to [Sharepoint](https://statoilsrm.sharepoint.com/sites/LCMlibrary) and click on Products summary. -5) Click "+ New" and add metadata for the product. Note: it must have the same name as the newly created LCM PSD Excel Sheet. NB! it is important to add metadata about the new product. If not, the data will not be uploaded to Azure when doing data synchronization. -6) Open the LCM web application and click "Synchronize with Sharepoint". - -## Deploy changes - -| Environment | Deployed how? | -|------------------------|------------------------------------------------------------------------------------------| -| [Testing][https://proxy-lost-circulation-material-test.radix.equinor.com] | Every commit to the `master` branch will be deployed automatically by Radix's "build-and-deploy"-feature| -| [Production][https://lost-circulation-material.app.radix.equinor.com] | Every commit to the `prod` branch will be deployed automatically by Radix's "build-and-deploy"-feature| - -## Update packages - -### Web - -You need yarn installed. - -```sh -cd web -yarn update -``` - -### API - -You need poetry installed. - -```sh -cd api -poetry update -``` diff --git a/secrets/.gitkeep b/secrets/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/web/Dockerfile b/web/Dockerfile index bcb70e31..12886cd0 100644 --- a/web/Dockerfile +++ b/web/Dockerfile @@ -1,7 +1,6 @@ -FROM node:23-alpine AS base +FROM node:25-alpine3.23 AS base ENV VITE_APPLICATION_OWNER=ovbra@equinor.com -ENV VITE_CLIENT_ID=1dbc1e96-268d-41ad-894a-92a9fb85f954 -ENV VITE_SCOPES="api://lost-circulation-material-api/Optimization.All.All" +ARG APPINSIGHTS_CON_STRING WORKDIR /code ADD package.json package-lock.json /code/ @@ -9,12 +8,15 @@ RUN npm install ADD ./ /code/ FROM base AS development + +ENV VITE_APPINSIGHTS_CON_STRING=$APPINSIGHTS_CON_STRING CMD ["npm","run", "start"] FROM base AS build -RUN npm run build +ARG APPINSIGHTS_CON_STRING +RUN export VITE_APPINSIGHTS_CON_STRING=$(echo $APPINSIGHTS_CON_STRING|base64 -d) && npm run build -FROM node:23-alpine AS prod +FROM node:25-alpine3.23 AS prod RUN npm install -g serve COPY --from=build /code/build /code/build EXPOSE 3000 diff --git a/web/package-lock.json b/web/package-lock.json index ab1cb129..9083199f 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -8,64 +8,50 @@ "name": "lcm-react", "version": "0.1.0", "dependencies": { - "@equinor/eds-core-react": "^0.43.0", - "@equinor/eds-icons": "^0.22.0", - "@equinor/eds-tokens": "^0.9.2", - "axios": "^1.7.9", - "react": "^19.0.0", - "react-dom": "^19.0.0", - "react-oauth2-code-pkce": "^1.22.2", + "@equinor/eds-core-react": "^2.3.7", + "@equinor/eds-icons": "^1.3.0", + "@equinor/eds-tokens": "^2.2.0", + "@microsoft/applicationinsights-react-js": "^19.3.8", + "@microsoft/applicationinsights-web": "^3.3.11", + "axios": "^1.13.6", + "react": "^19.2.4", + "react-dom": "^19.2.4", "react-toastify": "^11.0.5", - "recharts": "^2.15.1", - "styled-components": "^6.1.15" + "recharts": "^3.7.0", + "styled-components": "^6.3.11" }, "devDependencies": { - "@types/node": "^22.13.5", - "@types/react": "^19.0.10", - "@types/react-dom": "^19.0.4", - "@types/react-router-dom": "^5.3.3", - "@types/recharts": "^1.8.29", - "@types/styled-components": "^5.1.34", - "@vitejs/plugin-react": "^4.3.4", - "globals": "^15.15.0", - "typescript": "~5.7.2", - "vite": "^6.2.0", - "vite-plugin-csp-guard": "^2.0.2" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" + "@biomejs/biome": "2.4.4", + "@types/node": "^25.3.3", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@types/styled-components": "^5.1.36", + "@vitejs/plugin-react": "^5.1.4", + "globals": "^17.4.0", + "typescript": "~5.9.3", + "vite": "^7.3.1", + "vite-plugin-csp-guard": "^3.0.0" } }, "node_modules/@babel/code-frame": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", - "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.25.9", + "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz", - "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", "dev": true, "license": "MIT", "engines": { @@ -73,22 +59,22 @@ } }, "node_modules/@babel/core": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.9.tgz", - "integrity": "sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.9", - "@babel/helper-compilation-targets": "^7.26.5", - "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.9", - "@babel/parser": "^7.26.9", - "@babel/template": "^7.26.9", - "@babel/traverse": "^7.26.9", - "@babel/types": "^7.26.9", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -104,16 +90,16 @@ } }, "node_modules/@babel/generator": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.9.tgz", - "integrity": "sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==", + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.26.9", - "@babel/types": "^7.26.9", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" }, "engines": { @@ -121,14 +107,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz", - "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.26.5", - "@babel/helper-validator-option": "^7.25.9", + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -137,30 +123,40 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-module-imports": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", - "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", - "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9", - "@babel/traverse": "^7.25.9" + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -170,9 +166,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz", - "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", "dev": true, "license": "MIT", "engines": { @@ -180,9 +176,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", - "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true, "license": "MIT", "engines": { @@ -190,9 +186,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", - "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, "license": "MIT", "engines": { @@ -200,9 +196,9 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", - "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "dev": true, "license": "MIT", "engines": { @@ -210,27 +206,27 @@ } }, "node_modules/@babel/helpers": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.9.tgz", - "integrity": "sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", + "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.26.9", - "@babel/types": "^7.26.9" + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz", - "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.26.9" + "@babel/types": "^7.29.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -240,13 +236,13 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz", - "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -256,13 +252,13 @@ } }, "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz", - "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -272,157 +268,303 @@ } }, "node_modules/@babel/runtime": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.9.tgz", - "integrity": "sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", + "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", "license": "MIT", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/template": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz", - "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.26.2", - "@babel/parser": "^7.26.9", - "@babel/types": "^7.26.9" + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.9.tgz", - "integrity": "sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.9", - "@babel/parser": "^7.26.9", - "@babel/template": "^7.26.9", - "@babel/types": "^7.26.9", - "debug": "^4.3.1", - "globals": "^11.1.0" + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "dev": true, "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, "engines": { - "node": ">=4" + "node": ">=6.9.0" } }, - "node_modules/@babel/types": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz", - "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==", + "node_modules/@biomejs/biome": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.4.4.tgz", + "integrity": "sha512-tigwWS5KfJf0cABVd52NVaXyAVv4qpUXOWJ1rxFL8xF1RVoeS2q/LK+FHgYoKMclJCuRoCWAPy1IXaN9/mS61Q==", "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9" + "license": "MIT OR Apache-2.0", + "bin": { + "biome": "bin/biome" }, "engines": { - "node": ">=6.9.0" + "node": ">=14.21.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/biome" + }, + "optionalDependencies": { + "@biomejs/cli-darwin-arm64": "2.4.4", + "@biomejs/cli-darwin-x64": "2.4.4", + "@biomejs/cli-linux-arm64": "2.4.4", + "@biomejs/cli-linux-arm64-musl": "2.4.4", + "@biomejs/cli-linux-x64": "2.4.4", + "@biomejs/cli-linux-x64-musl": "2.4.4", + "@biomejs/cli-win32-arm64": "2.4.4", + "@biomejs/cli-win32-x64": "2.4.4" + } + }, + "node_modules/@biomejs/cli-darwin-arm64": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.4.4.tgz", + "integrity": "sha512-jZ+Xc6qvD6tTH5jM6eKX44dcbyNqJHssfl2nnwT6vma6B1sj7ZLTGIk6N5QwVBs5xGN52r3trk5fgd3sQ9We9A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-darwin-x64": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.4.4.tgz", + "integrity": "sha512-Dh1a/+W+SUCXhEdL7TiX3ArPTFCQKJTI1mGncZNWfO+6suk+gYA4lNyJcBB+pwvF49uw0pEbUS49BgYOY4hzUg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.4.4.tgz", + "integrity": "sha512-V/NFfbWhsUU6w+m5WYbBenlEAz8eYnSqRMDMAW3K+3v0tYVkNyZn8VU0XPxk/lOqNXLSCCrV7FmV/u3SjCBShg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64-musl": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.4.4.tgz", + "integrity": "sha512-+sPAXq3bxmFwhVFJnSwkSF5Rw2ZAJMH3MF6C9IveAEOdSpgajPhoQhbbAK12SehN9j2QrHpk4J/cHsa/HqWaYQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.4.4.tgz", + "integrity": "sha512-R4+ZCDtG9kHArasyBO+UBD6jr/FcFCTH8QkNTOCu0pRJzCWyWC4EtZa2AmUZB5h3e0jD7bRV2KvrENcf8rndBg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64-musl": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.4.4.tgz", + "integrity": "sha512-gGvFTGpOIQDb5CQ2VC0n9Z2UEqlP46c4aNgHmAMytYieTGEcfqhfCFnhs6xjt0S3igE6q5GLuIXtdQt3Izok+g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-arm64": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.4.4.tgz", + "integrity": "sha512-trzCqM7x+Gn832zZHgr28JoYagQNX4CZkUZhMUac2YxvvyDRLJDrb5m9IA7CaZLlX6lTQmADVfLEKP1et1Ma4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-x64": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.4.4.tgz", + "integrity": "sha512-gnOHKVPFAAPrpoPt2t+Q6FZ7RPry/FDV3GcpU53P3PtLNnQjBmKyN2Vh/JtqXet+H4pme8CC76rScwdjDcT1/A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" } }, "node_modules/@emotion/is-prop-valid": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", - "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.4.0.tgz", + "integrity": "sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==", "license": "MIT", "dependencies": { - "@emotion/memoize": "^0.8.1" + "@emotion/memoize": "^0.9.0" } }, "node_modules/@emotion/memoize": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", - "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==", + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", "license": "MIT" }, "node_modules/@emotion/unitless": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", - "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", "license": "MIT" }, "node_modules/@equinor/eds-core-react": { - "version": "0.43.0", - "resolved": "https://registry.npmjs.org/@equinor/eds-core-react/-/eds-core-react-0.43.0.tgz", - "integrity": "sha512-6sWUic7ezZhFT6DaIkBa8wXTqPV6W47Sc1jy9cKToETQVA3jlM4+usv3788jYiObZQd+CIGvkzxR+a/5Jpo6Dw==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.26.0", - "@equinor/eds-icons": "^0.22.0", - "@equinor/eds-tokens": "0.9.2", - "@equinor/eds-utils": "0.8.6", - "@floating-ui/react": "^0.27.2", - "@internationalized/date": "^3.6.0", - "@react-aria/utils": "^3.26.0", - "@react-stately/calendar": "^3.6.0", - "@react-stately/datepicker": "^3.11.0", - "@react-types/shared": "^3.26.0", - "@tanstack/react-virtual": "3.11.2", - "downshift": "9.0.8", - "react-aria": "^3.36.0" + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/@equinor/eds-core-react/-/eds-core-react-2.3.7.tgz", + "integrity": "sha512-u3WUwPoCbKK8SSP3RjqQ4Agu+LKK4PQ87nvc4AjrcETkCt4NSgKUoYTDfKqohPl0Ev2jmqn+LDnFAZxJcaUJKQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.6", + "@equinor/eds-icons": "^1.3.0", + "@equinor/eds-tokens": "^2.2.0", + "@equinor/eds-utils": "^2.0.0", + "@floating-ui/react": "^0.27.18", + "@internationalized/date": "^3.11.0", + "@react-aria/utils": "^3.33.0", + "@react-stately/calendar": "^3.9.2", + "@react-stately/datepicker": "^3.16.0", + "@react-types/shared": "^3.33.0", + "@tanstack/react-virtual": "3.13.18", + "downshift": "9.3.2", + "react-aria": "^3.46.0" }, "peerDependencies": { - "react": ">=16.8", - "react-dom": ">=16.8", - "styled-components": ">=5.1" + "react": "^19", + "react-dom": "^19", + "styled-components": "^6" } }, "node_modules/@equinor/eds-icons": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@equinor/eds-icons/-/eds-icons-0.22.0.tgz", - "integrity": "sha512-4SmPT67rUbl6qFyOCiSsue68EERgEGaXl9Xx6DkScW46AMbM6OdX3New1hctx1MIb6YdNlkHc/WwXTc+MG9j9Q==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@equinor/eds-icons/-/eds-icons-1.3.0.tgz", + "integrity": "sha512-n3HCm0t4J5OI8SbY10lb0pxDshlTdXOciLkUxoZpPJpBZx3DD2OzTA/RzRxTRee18viCtBC1eGorF3MHjeAuuA==", "license": "Apache-2.0" }, "node_modules/@equinor/eds-tokens": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/@equinor/eds-tokens/-/eds-tokens-0.9.2.tgz", - "integrity": "sha512-pDIFei0vsfN3GN12NKWqxskAkYBQd6+Dzjga2liuY81LfnlJs5g9NblamU9WY5w5YdVE5Z8FNjsMKDLs2JIWcw==", - "license": "MIT", - "engines": { - "node": ">=10.0.0", - "pnpm": ">=4" - } + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@equinor/eds-tokens/-/eds-tokens-2.2.0.tgz", + "integrity": "sha512-MUbv83ppGHzRBSgaZTkPqMU+2cAQsaDiE/b22GsIXnmptVH4NV5tyHJdz7Yrd1U7yKWO4L7IUwK849IBixyVyg==", + "license": "MIT" }, "node_modules/@equinor/eds-utils": { - "version": "0.8.6", - "resolved": "https://registry.npmjs.org/@equinor/eds-utils/-/eds-utils-0.8.6.tgz", - "integrity": "sha512-15AtxEoqovSZdXJprjt5YISTGJYiQCh35HPS3PjvbiJeY03ZXOq77zI0O12qUXxJmQ/MsadKxIxtfqAUmfRvtQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@equinor/eds-utils/-/eds-utils-2.0.0.tgz", + "integrity": "sha512-7VfLYkPA/qJst6HadcFXeLBhGiq3j1UaA5mW0zsIDurh/tesr+CziaXrPtopOfYJ5nIoQ9Zb0d6Mfx98XHLnjA==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.26.0", - "@equinor/eds-tokens": "0.9.2" + "@babel/runtime": "^7.28.4", + "@equinor/eds-tokens": "^2.0.0" }, "peerDependencies": { - "react": ">=16.8", - "react-dom": ">=16.8", - "styled-components": ">=5.1" + "react": "^19", + "react-dom": "^19", + "styled-components": "^6" } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.0.tgz", - "integrity": "sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", + "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", "cpu": [ "ppc64" ], @@ -437,9 +579,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.0.tgz", - "integrity": "sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", + "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", "cpu": [ "arm" ], @@ -454,9 +596,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.0.tgz", - "integrity": "sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", + "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", "cpu": [ "arm64" ], @@ -471,9 +613,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.0.tgz", - "integrity": "sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", + "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", "cpu": [ "x64" ], @@ -488,9 +630,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.0.tgz", - "integrity": "sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", + "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", "cpu": [ "arm64" ], @@ -505,9 +647,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.0.tgz", - "integrity": "sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", + "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", "cpu": [ "x64" ], @@ -522,9 +664,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.0.tgz", - "integrity": "sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", + "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", "cpu": [ "arm64" ], @@ -539,9 +681,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.0.tgz", - "integrity": "sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", + "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", "cpu": [ "x64" ], @@ -556,9 +698,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.0.tgz", - "integrity": "sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", + "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", "cpu": [ "arm" ], @@ -573,9 +715,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.0.tgz", - "integrity": "sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", + "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", "cpu": [ "arm64" ], @@ -590,9 +732,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.0.tgz", - "integrity": "sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", + "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", "cpu": [ "ia32" ], @@ -607,9 +749,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.0.tgz", - "integrity": "sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", + "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", "cpu": [ "loong64" ], @@ -624,9 +766,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.0.tgz", - "integrity": "sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", + "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", "cpu": [ "mips64el" ], @@ -641,9 +783,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.0.tgz", - "integrity": "sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", + "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", "cpu": [ "ppc64" ], @@ -658,9 +800,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.0.tgz", - "integrity": "sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", + "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", "cpu": [ "riscv64" ], @@ -675,9 +817,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.0.tgz", - "integrity": "sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", + "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", "cpu": [ "s390x" ], @@ -692,9 +834,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.0.tgz", - "integrity": "sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", + "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", "cpu": [ "x64" ], @@ -709,9 +851,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.0.tgz", - "integrity": "sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", + "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", "cpu": [ "arm64" ], @@ -726,9 +868,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.0.tgz", - "integrity": "sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", + "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", "cpu": [ "x64" ], @@ -743,9 +885,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.0.tgz", - "integrity": "sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", + "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", "cpu": [ "arm64" ], @@ -760,9 +902,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.0.tgz", - "integrity": "sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", + "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", "cpu": [ "x64" ], @@ -776,10 +918,27 @@ "node": ">=18" } }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", + "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.0.tgz", - "integrity": "sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", + "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", "cpu": [ "x64" ], @@ -794,9 +953,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.0.tgz", - "integrity": "sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", + "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", "cpu": [ "arm64" ], @@ -811,9 +970,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.0.tgz", - "integrity": "sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", + "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", "cpu": [ "ia32" ], @@ -828,9 +987,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.0.tgz", - "integrity": "sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", + "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", "cpu": [ "x64" ], @@ -845,32 +1004,32 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.6.9", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.9.tgz", - "integrity": "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.4.tgz", + "integrity": "sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg==", "license": "MIT", "dependencies": { - "@floating-ui/utils": "^0.2.9" + "@floating-ui/utils": "^0.2.10" } }, "node_modules/@floating-ui/dom": { - "version": "1.6.13", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.13.tgz", - "integrity": "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==", + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.5.tgz", + "integrity": "sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg==", "license": "MIT", "dependencies": { - "@floating-ui/core": "^1.6.0", - "@floating-ui/utils": "^0.2.9" + "@floating-ui/core": "^1.7.4", + "@floating-ui/utils": "^0.2.10" } }, "node_modules/@floating-ui/react": { - "version": "0.27.4", - "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.27.4.tgz", - "integrity": "sha512-05mXdkUiVh8NCEcYKQ2C9SV9IkZ9k/dFtYmaEIN2riLv80UHoXylgBM76cgPJYfLJM3dJz7UE5MOVH0FypMd2Q==", + "version": "0.27.18", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.27.18.tgz", + "integrity": "sha512-xJWJxvmy3a05j643gQt+pRbht5XnTlGpsEsAPnMi5F5YTOEEJymA90uZKBD8OvIv5XvZ1qi4GcccSlqT3Bq44Q==", "license": "MIT", "dependencies": { - "@floating-ui/react-dom": "^2.1.2", - "@floating-ui/utils": "^0.2.9", + "@floating-ui/react-dom": "^2.1.7", + "@floating-ui/utils": "^0.2.10", "tabbable": "^6.0.0" }, "peerDependencies": { @@ -879,12 +1038,12 @@ } }, "node_modules/@floating-ui/react-dom": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.2.tgz", - "integrity": "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==", + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.7.tgz", + "integrity": "sha512-0tLRojf/1Go2JgEVm+3Frg9A3IW8bJgKgdO0BN5RkF//ufuz2joZM63Npau2ff3J6lUVYgDSNzNkR+aH3IVfjg==", "license": "MIT", "dependencies": { - "@floating-ui/dom": "^1.0.0" + "@floating-ui/dom": "^1.7.5" }, "peerDependencies": { "react": ">=16.8.0", @@ -892,75 +1051,75 @@ } }, "node_modules/@floating-ui/utils": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz", - "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==", + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", + "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", "license": "MIT" }, "node_modules/@formatjs/ecma402-abstract": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.3.3.tgz", - "integrity": "sha512-pJT1OkhplSmvvr6i3CWTPvC/FGC06MbN5TNBfRO6Ox62AEz90eMq+dVvtX9Bl3jxCEkS0tATzDarRZuOLw7oFg==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.3.6.tgz", + "integrity": "sha512-HJnTFeRM2kVFVr5gr5kH1XP6K0JcJtE7Lzvtr3FS/so5f1kpsqqqxy5JF+FRaO6H2qmcMfAUIox7AJteieRtVw==", "license": "MIT", "dependencies": { - "@formatjs/fast-memoize": "2.2.6", - "@formatjs/intl-localematcher": "0.6.0", - "decimal.js": "10", - "tslib": "2" + "@formatjs/fast-memoize": "2.2.7", + "@formatjs/intl-localematcher": "0.6.2", + "decimal.js": "^10.4.3", + "tslib": "^2.8.0" } }, "node_modules/@formatjs/fast-memoize": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.6.tgz", - "integrity": "sha512-luIXeE2LJbQnnzotY1f2U2m7xuQNj2DA8Vq4ce1BY9ebRZaoPB1+8eZ6nXpLzsxuW5spQxr7LdCg+CApZwkqkw==", + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-2.2.7.tgz", + "integrity": "sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ==", "license": "MIT", "dependencies": { - "tslib": "2" + "tslib": "^2.8.0" } }, "node_modules/@formatjs/icu-messageformat-parser": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.11.1.tgz", - "integrity": "sha512-o0AhSNaOfKoic0Sn1GkFCK4MxdRsw7mPJ5/rBpIqdvcC7MIuyUSW8WChUEvrK78HhNpYOgqCQbINxCTumJLzZA==", + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.11.4.tgz", + "integrity": "sha512-7kR78cRrPNB4fjGFZg3Rmj5aah8rQj9KPzuLsmcSn4ipLXQvC04keycTI1F7kJYDwIXtT2+7IDEto842CfZBtw==", "license": "MIT", "dependencies": { - "@formatjs/ecma402-abstract": "2.3.3", - "@formatjs/icu-skeleton-parser": "1.8.13", - "tslib": "2" + "@formatjs/ecma402-abstract": "2.3.6", + "@formatjs/icu-skeleton-parser": "1.8.16", + "tslib": "^2.8.0" } }, "node_modules/@formatjs/icu-skeleton-parser": { - "version": "1.8.13", - "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.13.tgz", - "integrity": "sha512-N/LIdTvVc1TpJmMt2jVg0Fr1F7Q1qJPdZSCs19unMskCmVQ/sa0H9L8PWt13vq+gLdLg1+pPsvBLydL1Apahjg==", + "version": "1.8.16", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.16.tgz", + "integrity": "sha512-H13E9Xl+PxBd8D5/6TVUluSpxGNvFSlN/b3coUp0e0JpuWXXnQDiavIpY3NnvSp4xhEMoXyyBvVfdFX8jglOHQ==", "license": "MIT", "dependencies": { - "@formatjs/ecma402-abstract": "2.3.3", - "tslib": "2" + "@formatjs/ecma402-abstract": "2.3.6", + "tslib": "^2.8.0" } }, "node_modules/@formatjs/intl-localematcher": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.6.0.tgz", - "integrity": "sha512-4rB4g+3hESy1bHSBG3tDFaMY2CH67iT7yne1e+0CLTsGLDcmoEWWpJjjpWVaYgYfYuohIRuo0E+N536gd2ZHZA==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.6.2.tgz", + "integrity": "sha512-XOMO2Hupl0wdd172Y06h6kLpBz6Dv+J4okPLl4LPtzbr8f66WbIoy4ev98EBuZ6ZK4h5ydTN6XneT4QVpD7cdA==", "license": "MIT", "dependencies": { - "tslib": "2" + "tslib": "^2.8.0" } }, "node_modules/@internationalized/date": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.7.0.tgz", - "integrity": "sha512-VJ5WS3fcVx0bejE/YHfbDKR/yawZgKqn/if+oEeLqNwBtPzVB06olkfcnojTmEMX+gTpH+FlQ69SHNitJ8/erQ==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.11.0.tgz", + "integrity": "sha512-BOx5huLAWhicM9/ZFs84CzP+V3gBW6vlpM02yzsdYC7TGlZJX1OJiEEHcSayF00Z+3jLlm4w79amvSt6RqKN3Q==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0" } }, "node_modules/@internationalized/message": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/@internationalized/message/-/message-3.1.6.tgz", - "integrity": "sha512-JxbK3iAcTIeNr1p0WIFg/wQJjIzJt9l/2KNY/48vXV7GRGZSv3zMxJsce008fZclk2cDC8y0Ig3odceHO7EfNQ==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/@internationalized/message/-/message-3.1.8.tgz", + "integrity": "sha512-Rwk3j/TlYZhn3HQ6PyXUV0XP9Uv42jqZGNegt0BXlxjE6G3+LwHjbQZAGHhCnCPdaA6Tvd3ma/7QzLlLkJxAWA==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0", @@ -968,52 +1127,49 @@ } }, "node_modules/@internationalized/number": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@internationalized/number/-/number-3.6.0.tgz", - "integrity": "sha512-PtrRcJVy7nw++wn4W2OuePQQfTqDzfusSuY1QTtui4wa7r+rGVtR75pO8CyKvHvzyQYi3Q1uO5sY0AsB4e65Bw==", + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/@internationalized/number/-/number-3.6.5.tgz", + "integrity": "sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0" } }, "node_modules/@internationalized/string": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/@internationalized/string/-/string-3.2.5.tgz", - "integrity": "sha512-rKs71Zvl2OKOHM+mzAFMIyqR5hI1d1O6BBkMK2/lkfg3fkmVh9Eeg0awcA8W2WqYqDOv6a86DIOlFpggwLtbuw==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/@internationalized/string/-/string-3.2.7.tgz", + "integrity": "sha512-D4OHBjrinH+PFZPvfCXvG28n2LSykWcJ7GIioQL+ok0LON15SdfoUssoHzzOUmVZLbRoREsQXVzA6r8JKsbP6A==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0" } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", - "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", "dev": true, "license": "MIT", - "engines": { - "node": ">=6.0.0" + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, "license": "MIT", "engines": { @@ -1021,16 +1177,16 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, "license": "MIT", "dependencies": { @@ -1038,17 +1194,203 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@microsoft/applicationinsights-analytics-js": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-analytics-js/-/applicationinsights-analytics-js-3.3.11.tgz", + "integrity": "sha512-33fS5Y7uPgckP8yWqCAoWpWerA+d3RUC2lv6kkfJQM/V2KHeN4CGDtyXXWpq5vSZjE9BESXao13iBq4wiWit8Q==", + "license": "MIT", + "dependencies": { + "@microsoft/applicationinsights-common": "3.3.11", + "@microsoft/applicationinsights-core-js": "3.3.11", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-utils": ">= 0.11.8 < 2.x" + }, + "peerDependencies": { + "tslib": ">= 1.0.0" + } + }, + "node_modules/@microsoft/applicationinsights-cfgsync-js": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-cfgsync-js/-/applicationinsights-cfgsync-js-3.3.11.tgz", + "integrity": "sha512-HdBc/ldMZpqGtzAFDs49o82wTdKRX2B0BzmjgS+D4MrS7CLth4MxLHJHOpmTI2bmc/S4T8n32LlFkaQCvWb9ig==", + "license": "MIT", + "dependencies": { + "@microsoft/applicationinsights-common": "3.3.11", + "@microsoft/applicationinsights-core-js": "3.3.11", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.4 < 2.x", + "@nevware21/ts-utils": ">= 0.11.8 < 2.x" + }, + "peerDependencies": { + "tslib": ">= 1.0.0" + } + }, + "node_modules/@microsoft/applicationinsights-channel-js": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-3.3.11.tgz", + "integrity": "sha512-0ex/mxTf5R+P5WSvdU8Hgbeg8VzQ0XvcnjKQdmQy05ycScnKevt8an3DEPikOFqOKDi59L5hUETZlcdhesnVtg==", + "license": "MIT", + "dependencies": { + "@microsoft/applicationinsights-common": "3.3.11", + "@microsoft/applicationinsights-core-js": "3.3.11", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.4 < 2.x", + "@nevware21/ts-utils": ">= 0.11.8 < 2.x" + }, + "peerDependencies": { + "tslib": ">= 1.0.0" + } + }, + "node_modules/@microsoft/applicationinsights-common": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-common/-/applicationinsights-common-3.3.11.tgz", + "integrity": "sha512-OIe5vL56lkmIsRsI21QqbGpF8gF/UzUP4mlEhGWyG2UMskdtWrY+c+xAynyNDsAjhKKge+Rrs/xkpC0Fo0QrhQ==", + "license": "MIT", + "dependencies": { + "@microsoft/applicationinsights-core-js": "3.3.11", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-utils": ">= 0.11.8 < 2.x" + }, + "peerDependencies": { + "tslib": ">= 1.0.0" + } + }, + "node_modules/@microsoft/applicationinsights-core-js": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-3.3.11.tgz", + "integrity": "sha512-WlBY1sKDNL62T++NifgFCyDuOoNUNrVILfnHubOzgU/od7MFEQYWU8EZyDcBC/+Z8e3TD6jfixurYtWoUC+6Eg==", + "license": "MIT", + "dependencies": { + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.4 < 2.x", + "@nevware21/ts-utils": ">= 0.11.8 < 2.x" + }, + "peerDependencies": { + "tslib": ">= 1.0.0" + } + }, + "node_modules/@microsoft/applicationinsights-dependencies-js": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-dependencies-js/-/applicationinsights-dependencies-js-3.3.11.tgz", + "integrity": "sha512-+D7vBHvLWFveZmg1PCbDhpw/tiD+/AnptzEoV8IsM9wPbiHPGHdni9IDMrTJZdJZVafO0GxnxOJNpir8QTdO8g==", + "license": "MIT", + "dependencies": { + "@microsoft/applicationinsights-common": "3.3.11", + "@microsoft/applicationinsights-core-js": "3.3.11", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.4 < 2.x", + "@nevware21/ts-utils": ">= 0.11.8 < 2.x" + }, + "peerDependencies": { + "tslib": ">= 1.0.0" + } + }, + "node_modules/@microsoft/applicationinsights-properties-js": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-properties-js/-/applicationinsights-properties-js-3.3.11.tgz", + "integrity": "sha512-GOyIV8QziFop/LelZW1LAKwhGvtjzN7d47NkSRh9ZyZPW/ahWifakdQ6mZfLcL2uTyTmpcK8JtMtfNADo77NZg==", + "license": "MIT", + "dependencies": { + "@microsoft/applicationinsights-common": "3.3.11", + "@microsoft/applicationinsights-core-js": "3.3.11", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-utils": ">= 0.11.8 < 2.x" + }, + "peerDependencies": { + "tslib": ">= 1.0.0" + } + }, + "node_modules/@microsoft/applicationinsights-react-js": { + "version": "19.3.8", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-react-js/-/applicationinsights-react-js-19.3.8.tgz", + "integrity": "sha512-Y6KYRxXxkj1lunZcPUEfVelttO7i4Q6WFQE30wyV0Vu1A8USh9/JjRpTVItk7Vt11DQSH9nh3hjYX3p64SE3vA==", + "license": "MIT", + "dependencies": { + "@microsoft/applicationinsights-common": "^3.3.10", + "@microsoft/applicationinsights-core-js": "^3.3.10", + "@microsoft/applicationinsights-shims": "^3.0.1", + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-utils": ">= 0.11.3 < 2.x" + }, + "peerDependencies": { + "history": ">= 4.10.1", + "react": ">= 19.0.0", + "tslib": "*" + } + }, + "node_modules/@microsoft/applicationinsights-shims": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-shims/-/applicationinsights-shims-3.0.1.tgz", + "integrity": "sha512-DKwboF47H1nb33rSUfjqI6ryX29v+2QWcTrRvcQDA32AZr5Ilkr7whOOSsD1aBzwqX0RJEIP1Z81jfE3NBm/Lg==", + "license": "MIT", + "dependencies": { + "@nevware21/ts-utils": ">= 0.9.4 < 2.x" + } + }, + "node_modules/@microsoft/applicationinsights-web": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-web/-/applicationinsights-web-3.3.11.tgz", + "integrity": "sha512-LEI6LhfLFzBfPJ4j5TTPNC8LxwDpiJZSeyD2VVU3EPN2RtK+15vEL0oONaSV/AsWnDrwH3DIku0Nm+EVRJ4pNQ==", + "license": "MIT", + "dependencies": { + "@microsoft/applicationinsights-analytics-js": "3.3.11", + "@microsoft/applicationinsights-cfgsync-js": "3.3.11", + "@microsoft/applicationinsights-channel-js": "3.3.11", + "@microsoft/applicationinsights-common": "3.3.11", + "@microsoft/applicationinsights-core-js": "3.3.11", + "@microsoft/applicationinsights-dependencies-js": "3.3.11", + "@microsoft/applicationinsights-properties-js": "3.3.11", + "@microsoft/applicationinsights-shims": "3.0.1", + "@microsoft/dynamicproto-js": "^2.0.3", + "@nevware21/ts-async": ">= 0.5.4 < 2.x", + "@nevware21/ts-utils": ">= 0.11.8 < 2.x" + }, + "peerDependencies": { + "tslib": ">= 1.0.0" + } + }, + "node_modules/@microsoft/dynamicproto-js": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@microsoft/dynamicproto-js/-/dynamicproto-js-2.0.3.tgz", + "integrity": "sha512-JTWTU80rMy3mdxOjjpaiDQsTLZ6YSGGqsjURsY6AUQtIj0udlF/jYmhdLZu8693ZIC0T1IwYnFa0+QeiMnziBA==", + "license": "MIT", + "dependencies": { + "@nevware21/ts-utils": ">= 0.10.4 < 2.x" + } + }, + "node_modules/@nevware21/ts-async": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@nevware21/ts-async/-/ts-async-0.5.5.tgz", + "integrity": "sha512-vwqaL05iJPjLeh5igPi8MeeAu10i+Aq7xko1fbo9F5Si6MnVN5505qaV7AhSdk5MCBJVT/UYMk3kgInNjDb4Ig==", + "license": "MIT", + "dependencies": { + "@nevware21/ts-utils": ">= 0.12.2 < 2.x" + } + }, + "node_modules/@nevware21/ts-utils": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@nevware21/ts-utils/-/ts-utils-0.13.0.tgz", + "integrity": "sha512-F3mD+DsUn9OiZmZc5tg0oKqrJCtiCstwx+wE+DNzFYh2cCRUuzTYdK9zGGP/au2BWvbOQ6Tqlbjr2+dT1P3AlQ==", + "license": "MIT" + }, "node_modules/@react-aria/breadcrumbs": { - "version": "3.5.20", - "resolved": "https://registry.npmjs.org/@react-aria/breadcrumbs/-/breadcrumbs-3.5.20.tgz", - "integrity": "sha512-xqVSSDPpQuUFpJyIXMQv8L7zumk5CeGX7qTzo4XRvqm5T9qnNAX4XpYEMdktnLrQRY/OemCBScbx7SEwr0B3Kg==", + "version": "3.5.31", + "resolved": "https://registry.npmjs.org/@react-aria/breadcrumbs/-/breadcrumbs-3.5.31.tgz", + "integrity": "sha512-j8F2NMHFGT/n3alfFKdO4bvrY/ymtdL04GdclY7Vc6zOmCnWoEZ2UA0sFuV7Rk9dOL8fAtYV1kMD1ZRO/EMcGA==", "license": "Apache-2.0", "dependencies": { - "@react-aria/i18n": "^3.12.5", - "@react-aria/link": "^3.7.8", - "@react-aria/utils": "^3.27.0", - "@react-types/breadcrumbs": "^3.7.10", - "@react-types/shared": "^3.27.0", + "@react-aria/i18n": "^3.12.15", + "@react-aria/link": "^3.8.8", + "@react-aria/utils": "^3.33.0", + "@react-types/breadcrumbs": "^3.7.18", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1057,18 +1399,17 @@ } }, "node_modules/@react-aria/button": { - "version": "3.11.1", - "resolved": "https://registry.npmjs.org/@react-aria/button/-/button-3.11.1.tgz", - "integrity": "sha512-NSs2HxHSSPSuYy5bN+PMJzsCNDVsbm1fZ/nrWM2WWWHTBrx9OqyrEXZVV9ebzQCN9q0nzhwpf6D42zHIivWtJA==", + "version": "3.14.4", + "resolved": "https://registry.npmjs.org/@react-aria/button/-/button-3.14.4.tgz", + "integrity": "sha512-6mTPiSSQhELnWlnYJ1Tm1B0VL1GGKAs2PGAY3ZGbPGQPPDc6Wu82yIhuAO8TTFJrXkwAiqjQawgDLil/yB0V7Q==", "license": "Apache-2.0", "dependencies": { - "@react-aria/focus": "^3.19.1", - "@react-aria/interactions": "^3.23.0", - "@react-aria/toolbar": "3.0.0-beta.12", - "@react-aria/utils": "^3.27.0", - "@react-stately/toggle": "^3.8.1", - "@react-types/button": "^3.10.2", - "@react-types/shared": "^3.27.0", + "@react-aria/interactions": "^3.27.0", + "@react-aria/toolbar": "3.0.0-beta.23", + "@react-aria/utils": "^3.33.0", + "@react-stately/toggle": "^3.9.4", + "@react-types/button": "^3.15.0", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1077,20 +1418,20 @@ } }, "node_modules/@react-aria/calendar": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@react-aria/calendar/-/calendar-3.7.0.tgz", - "integrity": "sha512-9YUbgcox7cQgvZfQtL2BLLRsIuX4mJeclk9HkFoOsAu3RGO5HNsteah8FV54W8BMjm/bNRXIPUxtjTTP+1L6jg==", + "version": "3.9.4", + "resolved": "https://registry.npmjs.org/@react-aria/calendar/-/calendar-3.9.4.tgz", + "integrity": "sha512-0BvU8cj6uHn622Vp8Xd21XxXtvp3Bh4Yk1pHloqDNmUvvdBN+ol3Xsm5gG3XKKkZ+6CCEi6asCbLaEg3SZSbyg==", "license": "Apache-2.0", "dependencies": { - "@internationalized/date": "^3.7.0", - "@react-aria/i18n": "^3.12.5", - "@react-aria/interactions": "^3.23.0", - "@react-aria/live-announcer": "^3.4.1", - "@react-aria/utils": "^3.27.0", - "@react-stately/calendar": "^3.7.0", - "@react-types/button": "^3.10.2", - "@react-types/calendar": "^3.6.0", - "@react-types/shared": "^3.27.0", + "@internationalized/date": "^3.11.0", + "@react-aria/i18n": "^3.12.15", + "@react-aria/interactions": "^3.27.0", + "@react-aria/live-announcer": "^3.4.4", + "@react-aria/utils": "^3.33.0", + "@react-stately/calendar": "^3.9.2", + "@react-types/button": "^3.15.0", + "@react-types/calendar": "^3.8.2", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1099,21 +1440,21 @@ } }, "node_modules/@react-aria/checkbox": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/@react-aria/checkbox/-/checkbox-3.15.1.tgz", - "integrity": "sha512-ETgsMDZ0IZzRXy/OVlGkazm8T+PcMHoTvsxp0c+U82c8iqdITA+VJ615eBPOQh6OkkYIIn4cRn/e+69RmGzXng==", + "version": "3.16.4", + "resolved": "https://registry.npmjs.org/@react-aria/checkbox/-/checkbox-3.16.4.tgz", + "integrity": "sha512-FcZj6/f27mNp2+G5yxyOMRZbZQjJ1cuWvo0PPnnZ4ybSPUmSzI4uUZBk1wvsJVP9F9n+J2hZuYVCaN8pyzLweA==", "license": "Apache-2.0", "dependencies": { - "@react-aria/form": "^3.0.12", - "@react-aria/interactions": "^3.23.0", - "@react-aria/label": "^3.7.14", - "@react-aria/toggle": "^3.10.11", - "@react-aria/utils": "^3.27.0", - "@react-stately/checkbox": "^3.6.11", - "@react-stately/form": "^3.1.1", - "@react-stately/toggle": "^3.8.1", - "@react-types/checkbox": "^3.9.1", - "@react-types/shared": "^3.27.0", + "@react-aria/form": "^3.1.4", + "@react-aria/interactions": "^3.27.0", + "@react-aria/label": "^3.7.24", + "@react-aria/toggle": "^3.12.4", + "@react-aria/utils": "^3.33.0", + "@react-stately/checkbox": "^3.7.4", + "@react-stately/form": "^3.2.3", + "@react-stately/toggle": "^3.9.4", + "@react-types/checkbox": "^3.10.3", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1122,23 +1463,23 @@ } }, "node_modules/@react-aria/color": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@react-aria/color/-/color-3.0.3.tgz", - "integrity": "sha512-DDVma2107VHBfSuEnnmy+KJvXvxEXWSAooii2vlHHmQNb5x4rv4YTk+dP5GZl/7MgT8OgPTB9UHoC83bXFMDRA==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@react-aria/color/-/color-3.1.4.tgz", + "integrity": "sha512-LNFo0A9EEn2HZ8O/hASschH++M+krfezcp01XPv0/2ZQJ5b5u7VvJlUOEXtPsD4i9+BzvkSAEoVUXdlJie9V2Q==", "license": "Apache-2.0", "dependencies": { - "@react-aria/i18n": "^3.12.5", - "@react-aria/interactions": "^3.23.0", - "@react-aria/numberfield": "^3.11.10", - "@react-aria/slider": "^3.7.15", - "@react-aria/spinbutton": "^3.6.11", - "@react-aria/textfield": "^3.16.0", - "@react-aria/utils": "^3.27.0", - "@react-aria/visually-hidden": "^3.8.19", - "@react-stately/color": "^3.8.2", - "@react-stately/form": "^3.1.1", - "@react-types/color": "^3.0.2", - "@react-types/shared": "^3.27.0", + "@react-aria/i18n": "^3.12.15", + "@react-aria/interactions": "^3.27.0", + "@react-aria/numberfield": "^3.12.4", + "@react-aria/slider": "^3.8.4", + "@react-aria/spinbutton": "^3.7.1", + "@react-aria/textfield": "^3.18.4", + "@react-aria/utils": "^3.33.0", + "@react-aria/visually-hidden": "^3.8.30", + "@react-stately/color": "^3.9.4", + "@react-stately/form": "^3.2.3", + "@react-types/color": "^3.1.3", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1147,25 +1488,26 @@ } }, "node_modules/@react-aria/combobox": { - "version": "3.11.1", - "resolved": "https://registry.npmjs.org/@react-aria/combobox/-/combobox-3.11.1.tgz", - "integrity": "sha512-TTNbGhUuqxzPcJzd6hufOxuHzX0UARkw+0bl+TuCwNPQnqrcPf20EoOZvd3MHZwGq6GCP4QV+qo0uGx83RpUvA==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/@react-aria/combobox/-/combobox-3.14.2.tgz", + "integrity": "sha512-qwBeb8cMgK3xwrvXYHPtcphduD/k+oTcU18JHPvEO2kmR32knB33H81C2/Zoh4x86zTDJXaEtPscXBWuQ/M7AQ==", "license": "Apache-2.0", "dependencies": { - "@react-aria/i18n": "^3.12.5", - "@react-aria/listbox": "^3.14.0", - "@react-aria/live-announcer": "^3.4.1", - "@react-aria/menu": "^3.17.0", - "@react-aria/overlays": "^3.25.0", - "@react-aria/selection": "^3.22.0", - "@react-aria/textfield": "^3.16.0", - "@react-aria/utils": "^3.27.0", - "@react-stately/collections": "^3.12.1", - "@react-stately/combobox": "^3.10.2", - "@react-stately/form": "^3.1.1", - "@react-types/button": "^3.10.2", - "@react-types/combobox": "^3.13.2", - "@react-types/shared": "^3.27.0", + "@react-aria/focus": "^3.21.4", + "@react-aria/i18n": "^3.12.15", + "@react-aria/listbox": "^3.15.2", + "@react-aria/live-announcer": "^3.4.4", + "@react-aria/menu": "^3.20.0", + "@react-aria/overlays": "^3.31.1", + "@react-aria/selection": "^3.27.1", + "@react-aria/textfield": "^3.18.4", + "@react-aria/utils": "^3.33.0", + "@react-stately/collections": "^3.12.9", + "@react-stately/combobox": "^3.12.2", + "@react-stately/form": "^3.2.3", + "@react-types/button": "^3.15.0", + "@react-types/combobox": "^3.13.11", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1174,28 +1516,28 @@ } }, "node_modules/@react-aria/datepicker": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/@react-aria/datepicker/-/datepicker-3.13.0.tgz", - "integrity": "sha512-TmJan65P3Vk7VDBNW5rH9Z25cAn0vk8TEtaP3boCs8wJFE+HbEuB8EqLxBFu47khtuKTEqDP3dTlUh2Vt/f7Xw==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@react-aria/datepicker/-/datepicker-3.16.0.tgz", + "integrity": "sha512-QynYHIHE+wvuGopl/k05tphmDpykpfZ3l3eKnUfGrqvAYJEeCOyS0qoMlw7Vq3NscMLFbJI6ajqBmlmtgFNiSA==", "license": "Apache-2.0", "dependencies": { - "@internationalized/date": "^3.7.0", - "@internationalized/number": "^3.6.0", - "@internationalized/string": "^3.2.5", - "@react-aria/focus": "^3.19.1", - "@react-aria/form": "^3.0.12", - "@react-aria/i18n": "^3.12.5", - "@react-aria/interactions": "^3.23.0", - "@react-aria/label": "^3.7.14", - "@react-aria/spinbutton": "^3.6.11", - "@react-aria/utils": "^3.27.0", - "@react-stately/datepicker": "^3.12.0", - "@react-stately/form": "^3.1.1", - "@react-types/button": "^3.10.2", - "@react-types/calendar": "^3.6.0", - "@react-types/datepicker": "^3.10.0", - "@react-types/dialog": "^3.5.15", - "@react-types/shared": "^3.27.0", + "@internationalized/date": "^3.11.0", + "@internationalized/number": "^3.6.5", + "@internationalized/string": "^3.2.7", + "@react-aria/focus": "^3.21.4", + "@react-aria/form": "^3.1.4", + "@react-aria/i18n": "^3.12.15", + "@react-aria/interactions": "^3.27.0", + "@react-aria/label": "^3.7.24", + "@react-aria/spinbutton": "^3.7.1", + "@react-aria/utils": "^3.33.0", + "@react-stately/datepicker": "^3.16.0", + "@react-stately/form": "^3.2.3", + "@react-types/button": "^3.15.0", + "@react-types/calendar": "^3.8.2", + "@react-types/datepicker": "^3.13.4", + "@react-types/dialog": "^3.5.23", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1204,16 +1546,16 @@ } }, "node_modules/@react-aria/dialog": { - "version": "3.5.21", - "resolved": "https://registry.npmjs.org/@react-aria/dialog/-/dialog-3.5.21.tgz", - "integrity": "sha512-tBsn9swBhcptJ9QIm0+ur0PVR799N6qmGguva3rUdd+gfitknFScyT08d7AoMr9AbXYdJ+2R9XNSZ3H3uIWQMw==", + "version": "3.5.33", + "resolved": "https://registry.npmjs.org/@react-aria/dialog/-/dialog-3.5.33.tgz", + "integrity": "sha512-C5FpLAMJU6gQU8gztWKlEJ2A0k/JKl0YijNOv3Lizk+vUdF5njROSrmFs16bY5Hd6ycmsK9x/Pqkq3m/OpNFXA==", "license": "Apache-2.0", "dependencies": { - "@react-aria/focus": "^3.19.1", - "@react-aria/overlays": "^3.25.0", - "@react-aria/utils": "^3.27.0", - "@react-types/dialog": "^3.5.15", - "@react-types/shared": "^3.27.0", + "@react-aria/interactions": "^3.27.0", + "@react-aria/overlays": "^3.31.1", + "@react-aria/utils": "^3.33.0", + "@react-types/dialog": "^3.5.23", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1222,15 +1564,15 @@ } }, "node_modules/@react-aria/disclosure": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@react-aria/disclosure/-/disclosure-3.0.1.tgz", - "integrity": "sha512-rNH8RFcePoAQizcqB7KuHbBOr7sPsysFKCUwbVSOXLPgvCfXKafIhjgFJVqekfsbn5zWvkcTupnzGVJj/F9p+g==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@react-aria/disclosure/-/disclosure-3.1.2.tgz", + "integrity": "sha512-UQ/CmWcdcROfRTMtvfsnYHrEsPPNbwZifZ/UErQpbvU4kzal2N+PpuP3+kpdf4G7TeMt+uJ8S9dLzyFVijOj9A==", "license": "Apache-2.0", "dependencies": { - "@react-aria/ssr": "^3.9.7", - "@react-aria/utils": "^3.27.0", - "@react-stately/disclosure": "^3.0.1", - "@react-types/button": "^3.10.2", + "@react-aria/ssr": "^3.9.10", + "@react-aria/utils": "^3.33.0", + "@react-stately/disclosure": "^3.0.10", + "@react-types/button": "^3.15.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1239,20 +1581,21 @@ } }, "node_modules/@react-aria/dnd": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@react-aria/dnd/-/dnd-3.8.1.tgz", - "integrity": "sha512-FoXYQ4z33E9YBzIGRJM1B1oZep6CvEWgXvjCZGURatjr3qG7vf95mOqA5kVd9bjLL7QK4w0ujJWEBfog3WmufA==", + "version": "3.11.5", + "resolved": "https://registry.npmjs.org/@react-aria/dnd/-/dnd-3.11.5.tgz", + "integrity": "sha512-3IGrABfK8Cf6/b/uEmGEDGeubWKMUK3umWunF/tdkWBnIaxpdj4gRkWFMw7siWQYnqir6AN567nrWXtHFcLKsA==", "license": "Apache-2.0", "dependencies": { - "@internationalized/string": "^3.2.5", - "@react-aria/i18n": "^3.12.5", - "@react-aria/interactions": "^3.23.0", - "@react-aria/live-announcer": "^3.4.1", - "@react-aria/overlays": "^3.25.0", - "@react-aria/utils": "^3.27.0", - "@react-stately/dnd": "^3.5.1", - "@react-types/button": "^3.10.2", - "@react-types/shared": "^3.27.0", + "@internationalized/string": "^3.2.7", + "@react-aria/i18n": "^3.12.15", + "@react-aria/interactions": "^3.27.0", + "@react-aria/live-announcer": "^3.4.4", + "@react-aria/overlays": "^3.31.1", + "@react-aria/utils": "^3.33.0", + "@react-stately/collections": "^3.12.9", + "@react-stately/dnd": "^3.7.3", + "@react-types/button": "^3.15.0", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1261,14 +1604,14 @@ } }, "node_modules/@react-aria/focus": { - "version": "3.19.1", - "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.19.1.tgz", - "integrity": "sha512-bix9Bu1Ue7RPcYmjwcjhB14BMu2qzfJ3tMQLqDc9pweJA66nOw8DThy3IfVr8Z7j2PHktOLf9kcbiZpydKHqzg==", + "version": "3.21.4", + "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.21.4.tgz", + "integrity": "sha512-6gz+j9ip0/vFRTKJMl3R30MHopn4i19HqqLfSQfElxJD+r9hBnYG1Q6Wd/kl/WRR1+CALn2F+rn06jUnf5sT8Q==", "license": "Apache-2.0", "dependencies": { - "@react-aria/interactions": "^3.23.0", - "@react-aria/utils": "^3.27.0", - "@react-types/shared": "^3.27.0", + "@react-aria/interactions": "^3.27.0", + "@react-aria/utils": "^3.33.0", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0", "clsx": "^2.0.0" }, @@ -1278,15 +1621,15 @@ } }, "node_modules/@react-aria/form": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/@react-aria/form/-/form-3.0.12.tgz", - "integrity": "sha512-8uvPYEd3GDyGt5NRJIzdWW1Ry5HLZq37vzRZKUW8alZ2upFMH3KJJG55L9GP59KiF6zBrYBebvI/YK1Ye1PE1g==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@react-aria/form/-/form-3.1.4.tgz", + "integrity": "sha512-GjPS85cE/34zal3vs6MOi7FxUsXwbxN4y6l1LFor2g92UK97gVobp238f3xdMW2T8IuaWGcnHeYFg+cjiZ51pQ==", "license": "Apache-2.0", "dependencies": { - "@react-aria/interactions": "^3.23.0", - "@react-aria/utils": "^3.27.0", - "@react-stately/form": "^3.1.1", - "@react-types/shared": "^3.27.0", + "@react-aria/interactions": "^3.27.0", + "@react-aria/utils": "^3.33.0", + "@react-stately/form": "^3.2.3", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1295,23 +1638,23 @@ } }, "node_modules/@react-aria/grid": { - "version": "3.11.1", - "resolved": "https://registry.npmjs.org/@react-aria/grid/-/grid-3.11.1.tgz", - "integrity": "sha512-Wg8m68RtNWfkhP3Qjrrsl1q1et8QCjXPMRsYgKBahYRS0kq2MDcQ+UBdG1fiCQn/MfNImhTUGVeQX276dy1lww==", + "version": "3.14.7", + "resolved": "https://registry.npmjs.org/@react-aria/grid/-/grid-3.14.7.tgz", + "integrity": "sha512-8eaJThNHUs75Xf4+FQC2NKQtTOVYkkDdA8VbfbqG06oYDAn7ETb1yhbwoqh1jOv7MezCNkYjyFe4ADsz2rBVcw==", "license": "Apache-2.0", "dependencies": { - "@react-aria/focus": "^3.19.1", - "@react-aria/i18n": "^3.12.5", - "@react-aria/interactions": "^3.23.0", - "@react-aria/live-announcer": "^3.4.1", - "@react-aria/selection": "^3.22.0", - "@react-aria/utils": "^3.27.0", - "@react-stately/collections": "^3.12.1", - "@react-stately/grid": "^3.10.1", - "@react-stately/selection": "^3.19.0", - "@react-types/checkbox": "^3.9.1", - "@react-types/grid": "^3.2.11", - "@react-types/shared": "^3.27.0", + "@react-aria/focus": "^3.21.4", + "@react-aria/i18n": "^3.12.15", + "@react-aria/interactions": "^3.27.0", + "@react-aria/live-announcer": "^3.4.4", + "@react-aria/selection": "^3.27.1", + "@react-aria/utils": "^3.33.0", + "@react-stately/collections": "^3.12.9", + "@react-stately/grid": "^3.11.8", + "@react-stately/selection": "^3.20.8", + "@react-types/checkbox": "^3.10.3", + "@react-types/grid": "^3.3.7", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1320,21 +1663,20 @@ } }, "node_modules/@react-aria/gridlist": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@react-aria/gridlist/-/gridlist-3.10.1.tgz", - "integrity": "sha512-11FlupBg5C9ehs7R6OjqMPWEOLK/4IuSrq7D1xU+Hnm7ZYI/KKcCXvNMjMmnOz/gGzOmfgVwz5PIKaY9aZarEg==", + "version": "3.14.3", + "resolved": "https://registry.npmjs.org/@react-aria/gridlist/-/gridlist-3.14.3.tgz", + "integrity": "sha512-t3nr29nU5jRG9MdWe9aiMd02V8o0pmidLU/7c4muWAu7hEH+IYdeDthGDdXL9tXAom/oQ+6yt6sOfLxpsVNmGA==", "license": "Apache-2.0", "dependencies": { - "@react-aria/focus": "^3.19.1", - "@react-aria/grid": "^3.11.1", - "@react-aria/i18n": "^3.12.5", - "@react-aria/interactions": "^3.23.0", - "@react-aria/selection": "^3.22.0", - "@react-aria/utils": "^3.27.0", - "@react-stately/collections": "^3.12.1", - "@react-stately/list": "^3.11.2", - "@react-stately/tree": "^3.8.7", - "@react-types/shared": "^3.27.0", + "@react-aria/focus": "^3.21.4", + "@react-aria/grid": "^3.14.7", + "@react-aria/i18n": "^3.12.15", + "@react-aria/interactions": "^3.27.0", + "@react-aria/selection": "^3.27.1", + "@react-aria/utils": "^3.33.0", + "@react-stately/list": "^3.13.3", + "@react-stately/tree": "^3.9.5", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1343,18 +1685,18 @@ } }, "node_modules/@react-aria/i18n": { - "version": "3.12.5", - "resolved": "https://registry.npmjs.org/@react-aria/i18n/-/i18n-3.12.5.tgz", - "integrity": "sha512-ooeop2pTG94PuaHoN2OTk2hpkqVuoqgEYxRvnc1t7DVAtsskfhS/gVOTqyWGsxvwAvRi7m/CnDu6FYdeQ/bK5w==", + "version": "3.12.15", + "resolved": "https://registry.npmjs.org/@react-aria/i18n/-/i18n-3.12.15.tgz", + "integrity": "sha512-3CrAN7ORVHrckvTmbPq76jFZabqq+rScosGT5+ElircJ5rF5+JcdT99Hp5Xg6R10jk74e8G3xiqdYsUd+7iJMA==", "license": "Apache-2.0", "dependencies": { - "@internationalized/date": "^3.7.0", - "@internationalized/message": "^3.1.6", - "@internationalized/number": "^3.6.0", - "@internationalized/string": "^3.2.5", - "@react-aria/ssr": "^3.9.7", - "@react-aria/utils": "^3.27.0", - "@react-types/shared": "^3.27.0", + "@internationalized/date": "^3.11.0", + "@internationalized/message": "^3.1.8", + "@internationalized/number": "^3.6.5", + "@internationalized/string": "^3.2.7", + "@react-aria/ssr": "^3.9.10", + "@react-aria/utils": "^3.33.0", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1363,14 +1705,15 @@ } }, "node_modules/@react-aria/interactions": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.23.0.tgz", - "integrity": "sha512-0qR1atBIWrb7FzQ+Tmr3s8uH5mQdyRH78n0krYaG8tng9+u1JlSi8DGRSaC9ezKyNB84m7vHT207xnHXGeJ3Fg==", + "version": "3.27.0", + "resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.27.0.tgz", + "integrity": "sha512-D27pOy+0jIfHK60BB26AgqjjRFOYdvVSkwC31b2LicIzRCSPOSP06V4gMHuGmkhNTF4+YWDi1HHYjxIvMeiSlA==", "license": "Apache-2.0", "dependencies": { - "@react-aria/ssr": "^3.9.7", - "@react-aria/utils": "^3.27.0", - "@react-types/shared": "^3.27.0", + "@react-aria/ssr": "^3.9.10", + "@react-aria/utils": "^3.33.0", + "@react-stately/flags": "^3.1.2", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1379,13 +1722,13 @@ } }, "node_modules/@react-aria/label": { - "version": "3.7.14", - "resolved": "https://registry.npmjs.org/@react-aria/label/-/label-3.7.14.tgz", - "integrity": "sha512-EN1Md2YvcC4sMqBoggsGYUEGlTNqUfJZWzduSt29fbQp1rKU2KlybTe+TWxKq/r2fFd+4JsRXxMeJiwB3w2AQA==", + "version": "3.7.24", + "resolved": "https://registry.npmjs.org/@react-aria/label/-/label-3.7.24.tgz", + "integrity": "sha512-lcJbUy6xyicWKNgzfrXksrJ2CeCST2rDxGAvHOmUxSbFOm26kK710DjaFvtO4tICWh/TKW5mC3sm77soNcVUGA==", "license": "Apache-2.0", "dependencies": { - "@react-aria/utils": "^3.27.0", - "@react-types/shared": "^3.27.0", + "@react-aria/utils": "^3.33.0", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1393,17 +1736,32 @@ "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, + "node_modules/@react-aria/landmark": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@react-aria/landmark/-/landmark-3.0.9.tgz", + "integrity": "sha512-YYyluDBCXupnMh91ccE5g27fczjYmzPebHqTkVYjH4B6k45pOoqsMmWBCMnOTl0qOCeioI+daT8W0MamAZzoSw==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/utils": "^3.33.0", + "@react-types/shared": "^3.33.0", + "@swc/helpers": "^0.5.0", + "use-sync-external-store": "^1.6.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, "node_modules/@react-aria/link": { - "version": "3.7.8", - "resolved": "https://registry.npmjs.org/@react-aria/link/-/link-3.7.8.tgz", - "integrity": "sha512-oiXUPQLZmf9Q9Xehb/sG1QRxfo28NFKdh9w+unD12sHI6NdLMETl5MA4CYyTgI0dfMtTjtfrF68GCnWfc7JvXQ==", + "version": "3.8.8", + "resolved": "https://registry.npmjs.org/@react-aria/link/-/link-3.8.8.tgz", + "integrity": "sha512-hxQEvo5rrn2C0GOSwB/tROe+y//dyhmyXGbm8arDy6WF5Mj0wcjjrAu0/dhGYBqoltJa16iIEvs52xgzOC+f+Q==", "license": "Apache-2.0", "dependencies": { - "@react-aria/focus": "^3.19.1", - "@react-aria/interactions": "^3.23.0", - "@react-aria/utils": "^3.27.0", - "@react-types/link": "^3.5.10", - "@react-types/shared": "^3.27.0", + "@react-aria/interactions": "^3.27.0", + "@react-aria/utils": "^3.33.0", + "@react-types/link": "^3.6.6", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1412,19 +1770,19 @@ } }, "node_modules/@react-aria/listbox": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/@react-aria/listbox/-/listbox-3.14.0.tgz", - "integrity": "sha512-pyVbKavh8N8iyiwOx6I3JIcICvAzFXkKSFni1yarfgngJsJV3KSyOkzLomOfN9UhbjcV4sX61/fccwJuvlurlA==", + "version": "3.15.2", + "resolved": "https://registry.npmjs.org/@react-aria/listbox/-/listbox-3.15.2.tgz", + "integrity": "sha512-xcrgSediV8MaVmsuDrDPmWywF82/HOv+H+Y/dgr6GLCWl0XDj5Q7PyAhDzUsYdZNIne3B9muGh6IQc3HdkgWqg==", "license": "Apache-2.0", "dependencies": { - "@react-aria/interactions": "^3.23.0", - "@react-aria/label": "^3.7.14", - "@react-aria/selection": "^3.22.0", - "@react-aria/utils": "^3.27.0", - "@react-stately/collections": "^3.12.1", - "@react-stately/list": "^3.11.2", - "@react-types/listbox": "^3.5.4", - "@react-types/shared": "^3.27.0", + "@react-aria/interactions": "^3.27.0", + "@react-aria/label": "^3.7.24", + "@react-aria/selection": "^3.27.1", + "@react-aria/utils": "^3.33.0", + "@react-stately/collections": "^3.12.9", + "@react-stately/list": "^3.13.3", + "@react-types/listbox": "^3.7.5", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1433,33 +1791,33 @@ } }, "node_modules/@react-aria/live-announcer": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@react-aria/live-announcer/-/live-announcer-3.4.1.tgz", - "integrity": "sha512-4X2mcxgqLvvkqxv2l1n00jTzUxxe0kkLiapBGH1LHX/CxA1oQcHDqv8etJ2ZOwmS/MSBBiWnv3DwYHDOF6ubig==", + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@react-aria/live-announcer/-/live-announcer-3.4.4.tgz", + "integrity": "sha512-PTTBIjNRnrdJOIRTDGNifY2d//kA7GUAwRFJNOEwSNG4FW+Bq9awqLiflw0JkpyB0VNIwou6lqKPHZVLsGWOXA==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0" } }, "node_modules/@react-aria/menu": { - "version": "3.17.0", - "resolved": "https://registry.npmjs.org/@react-aria/menu/-/menu-3.17.0.tgz", - "integrity": "sha512-aiFvSv3G1YvPC0klJQ/9quB05xIDZzJ5Lt6/CykP0UwGK5i8GCqm6/cyFLwEXsS5ooUPxS3bqmdOsgdADSSgqg==", + "version": "3.20.0", + "resolved": "https://registry.npmjs.org/@react-aria/menu/-/menu-3.20.0.tgz", + "integrity": "sha512-BAsHuf7kTVmawNUkTUd5RB3ZvL6DQQT7hgZ2cYKd/1ZwYq4KO2wWGYdzyTOtK1qimZL0eyHyQwDYv4dNKBH4gw==", "license": "Apache-2.0", "dependencies": { - "@react-aria/focus": "^3.19.1", - "@react-aria/i18n": "^3.12.5", - "@react-aria/interactions": "^3.23.0", - "@react-aria/overlays": "^3.25.0", - "@react-aria/selection": "^3.22.0", - "@react-aria/utils": "^3.27.0", - "@react-stately/collections": "^3.12.1", - "@react-stately/menu": "^3.9.1", - "@react-stately/selection": "^3.19.0", - "@react-stately/tree": "^3.8.7", - "@react-types/button": "^3.10.2", - "@react-types/menu": "^3.9.14", - "@react-types/shared": "^3.27.0", + "@react-aria/focus": "^3.21.4", + "@react-aria/i18n": "^3.12.15", + "@react-aria/interactions": "^3.27.0", + "@react-aria/overlays": "^3.31.1", + "@react-aria/selection": "^3.27.1", + "@react-aria/utils": "^3.33.0", + "@react-stately/collections": "^3.12.9", + "@react-stately/menu": "^3.9.10", + "@react-stately/selection": "^3.20.8", + "@react-stately/tree": "^3.9.5", + "@react-types/button": "^3.15.0", + "@react-types/menu": "^3.10.6", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1468,36 +1826,37 @@ } }, "node_modules/@react-aria/meter": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/@react-aria/meter/-/meter-3.4.19.tgz", - "integrity": "sha512-IIA+gTHrNVbMuBgcqdGLEKd/ZiKM2hOUqS6uztbT15dwPJTmtfJiTWA2872PiY52p+gqPSanZuTc2TXYJa+rew==", + "version": "3.4.29", + "resolved": "https://registry.npmjs.org/@react-aria/meter/-/meter-3.4.29.tgz", + "integrity": "sha512-XAhJf8LlYQl+QQXqtpWvzjlrT8MZKEG6c8N3apC5DONgSKlCwfmDm4laGEJPqtuz3QGiOopsfSfyTFYHjWsfZw==", "license": "Apache-2.0", "dependencies": { - "@react-aria/progress": "^3.4.19", - "@react-types/meter": "^3.4.6", - "@react-types/shared": "^3.27.0", + "@react-aria/progress": "^3.4.29", + "@react-types/meter": "^3.4.14", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-aria/numberfield": { - "version": "3.11.10", - "resolved": "https://registry.npmjs.org/@react-aria/numberfield/-/numberfield-3.11.10.tgz", - "integrity": "sha512-bYbTfO9NbAKMFOfEGGs+lvlxk0I9L0lU3WD2PFQZWdaoBz9TCkL+vK0fJk1zsuKaVjeGsmHP9VesBPRmaP0MiA==", + "version": "3.12.4", + "resolved": "https://registry.npmjs.org/@react-aria/numberfield/-/numberfield-3.12.4.tgz", + "integrity": "sha512-TgKBjKOjyURzbqNR2wF4tSFmQKNK5DqE4QZSlQxpYYo1T6zuztkh+oTOUZ4IWCJymL5qLtuPfGHCZbR7B+DN2w==", "license": "Apache-2.0", "dependencies": { - "@react-aria/i18n": "^3.12.5", - "@react-aria/interactions": "^3.23.0", - "@react-aria/spinbutton": "^3.6.11", - "@react-aria/textfield": "^3.16.0", - "@react-aria/utils": "^3.27.0", - "@react-stately/form": "^3.1.1", - "@react-stately/numberfield": "^3.9.9", - "@react-types/button": "^3.10.2", - "@react-types/numberfield": "^3.8.8", - "@react-types/shared": "^3.27.0", + "@react-aria/i18n": "^3.12.15", + "@react-aria/interactions": "^3.27.0", + "@react-aria/spinbutton": "^3.7.1", + "@react-aria/textfield": "^3.18.4", + "@react-aria/utils": "^3.33.0", + "@react-stately/form": "^3.2.3", + "@react-stately/numberfield": "^3.10.4", + "@react-types/button": "^3.15.0", + "@react-types/numberfield": "^3.8.17", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1506,21 +1865,21 @@ } }, "node_modules/@react-aria/overlays": { - "version": "3.25.0", - "resolved": "https://registry.npmjs.org/@react-aria/overlays/-/overlays-3.25.0.tgz", - "integrity": "sha512-UEqJJ4duowrD1JvwXpPZreBuK79pbyNjNxFUVpFSskpGEJe3oCWwsSDKz7P1O7xbx5OYp+rDiY8fk/sE5rkaKw==", + "version": "3.31.1", + "resolved": "https://registry.npmjs.org/@react-aria/overlays/-/overlays-3.31.1.tgz", + "integrity": "sha512-U5BedzcXU97U5PWm4kIPnNoVpAs9KjTYfbkGx33vapmTVpGYhQyYW9eg6zW2E8ZKsyFJtQ/jkQnbWGen97aHSQ==", "license": "Apache-2.0", "dependencies": { - "@react-aria/focus": "^3.19.1", - "@react-aria/i18n": "^3.12.5", - "@react-aria/interactions": "^3.23.0", - "@react-aria/ssr": "^3.9.7", - "@react-aria/utils": "^3.27.0", - "@react-aria/visually-hidden": "^3.8.19", - "@react-stately/overlays": "^3.6.13", - "@react-types/button": "^3.10.2", - "@react-types/overlays": "^3.8.12", - "@react-types/shared": "^3.27.0", + "@react-aria/focus": "^3.21.4", + "@react-aria/i18n": "^3.12.15", + "@react-aria/interactions": "^3.27.0", + "@react-aria/ssr": "^3.9.10", + "@react-aria/utils": "^3.33.0", + "@react-aria/visually-hidden": "^3.8.30", + "@react-stately/overlays": "^3.6.22", + "@react-types/button": "^3.15.0", + "@react-types/overlays": "^3.9.3", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1529,16 +1888,16 @@ } }, "node_modules/@react-aria/progress": { - "version": "3.4.19", - "resolved": "https://registry.npmjs.org/@react-aria/progress/-/progress-3.4.19.tgz", - "integrity": "sha512-5HHnBJHqEUuY+dYsjIZDYsENeKr49VCuxeaDZ0OSahbOlloIOB1baCo/6jLBv1O1rwrAzZ2gCCPcVGed/cjrcw==", + "version": "3.4.29", + "resolved": "https://registry.npmjs.org/@react-aria/progress/-/progress-3.4.29.tgz", + "integrity": "sha512-orSaaFLX5LdD9UyxgBrmP1J/ivyEFX+5v4ENPQM5RH5+Hl+0OJa+8ozI0AfVKBqCYc89BOZfG7kzi7wFHACZcQ==", "license": "Apache-2.0", "dependencies": { - "@react-aria/i18n": "^3.12.5", - "@react-aria/label": "^3.7.14", - "@react-aria/utils": "^3.27.0", - "@react-types/progress": "^3.5.9", - "@react-types/shared": "^3.27.0", + "@react-aria/i18n": "^3.12.15", + "@react-aria/label": "^3.7.24", + "@react-aria/utils": "^3.33.0", + "@react-types/progress": "^3.5.17", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1547,20 +1906,20 @@ } }, "node_modules/@react-aria/radio": { - "version": "3.10.11", - "resolved": "https://registry.npmjs.org/@react-aria/radio/-/radio-3.10.11.tgz", - "integrity": "sha512-R150HsBFPr1jLMShI4aBM8heCa1k6h0KEvnFRfTAOBu+B9hMSZOPB+d6GQOwGPysNlbset90Kej8G15FGHjqiA==", + "version": "3.12.4", + "resolved": "https://registry.npmjs.org/@react-aria/radio/-/radio-3.12.4.tgz", + "integrity": "sha512-2sjBAE8++EtAAfjwPdrqEVswbzR4Mvcy4n8SvwUxTo02yESa9nolBzCSdAUFUmhrNj3MiMA+zLxQ+KACfUjJOg==", "license": "Apache-2.0", "dependencies": { - "@react-aria/focus": "^3.19.1", - "@react-aria/form": "^3.0.12", - "@react-aria/i18n": "^3.12.5", - "@react-aria/interactions": "^3.23.0", - "@react-aria/label": "^3.7.14", - "@react-aria/utils": "^3.27.0", - "@react-stately/radio": "^3.10.10", - "@react-types/radio": "^3.8.6", - "@react-types/shared": "^3.27.0", + "@react-aria/focus": "^3.21.4", + "@react-aria/form": "^3.1.4", + "@react-aria/i18n": "^3.12.15", + "@react-aria/interactions": "^3.27.0", + "@react-aria/label": "^3.7.24", + "@react-aria/utils": "^3.33.0", + "@react-stately/radio": "^3.11.4", + "@react-types/radio": "^3.9.3", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1569,18 +1928,18 @@ } }, "node_modules/@react-aria/searchfield": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/@react-aria/searchfield/-/searchfield-3.8.0.tgz", - "integrity": "sha512-AaZuH9YIWlMyE1m7cSjHCfOuQmlWN+w8HVW32TxeGGGL1kJsYAlSYWYHUyYFIKh245kq/m5zUxAxmw5Ygmnx5w==", + "version": "3.8.11", + "resolved": "https://registry.npmjs.org/@react-aria/searchfield/-/searchfield-3.8.11.tgz", + "integrity": "sha512-5R0prEC+jRFwPeJsK6G4RN8QG3V/+EaIuw9p79G1gFD+1dY81ZakiZIIJaLWRyO7AzYBGyC/QFHtz0m3KGQT/Q==", "license": "Apache-2.0", "dependencies": { - "@react-aria/i18n": "^3.12.5", - "@react-aria/textfield": "^3.16.0", - "@react-aria/utils": "^3.27.0", - "@react-stately/searchfield": "^3.5.9", - "@react-types/button": "^3.10.2", - "@react-types/searchfield": "^3.5.11", - "@react-types/shared": "^3.27.0", + "@react-aria/i18n": "^3.12.15", + "@react-aria/textfield": "^3.18.4", + "@react-aria/utils": "^3.33.0", + "@react-stately/searchfield": "^3.5.18", + "@react-types/button": "^3.15.0", + "@react-types/searchfield": "^3.6.7", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1589,24 +1948,24 @@ } }, "node_modules/@react-aria/select": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/@react-aria/select/-/select-3.15.1.tgz", - "integrity": "sha512-FOtY1tuHt0YTHwOEy/sf7LEIL+Nnkho3wJmfpWQuTxsvMCF7UJdQPYPd6/jGCcCdiqW7H4iqyjUkSp6nk/XRWQ==", + "version": "3.17.2", + "resolved": "https://registry.npmjs.org/@react-aria/select/-/select-3.17.2.tgz", + "integrity": "sha512-oMpHStyMluRf67qxrzH5Qfcvw6ETQgZT1Qw2xvAxQVRd5IBb0PfzZS7TGiULOcMLqXAUOC28O/ycUGrGRKLarg==", "license": "Apache-2.0", "dependencies": { - "@react-aria/form": "^3.0.12", - "@react-aria/i18n": "^3.12.5", - "@react-aria/interactions": "^3.23.0", - "@react-aria/label": "^3.7.14", - "@react-aria/listbox": "^3.14.0", - "@react-aria/menu": "^3.17.0", - "@react-aria/selection": "^3.22.0", - "@react-aria/utils": "^3.27.0", - "@react-aria/visually-hidden": "^3.8.19", - "@react-stately/select": "^3.6.10", - "@react-types/button": "^3.10.2", - "@react-types/select": "^3.9.9", - "@react-types/shared": "^3.27.0", + "@react-aria/form": "^3.1.4", + "@react-aria/i18n": "^3.12.15", + "@react-aria/interactions": "^3.27.0", + "@react-aria/label": "^3.7.24", + "@react-aria/listbox": "^3.15.2", + "@react-aria/menu": "^3.20.0", + "@react-aria/selection": "^3.27.1", + "@react-aria/utils": "^3.33.0", + "@react-aria/visually-hidden": "^3.8.30", + "@react-stately/select": "^3.9.1", + "@react-types/button": "^3.15.0", + "@react-types/select": "^3.12.1", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1615,17 +1974,17 @@ } }, "node_modules/@react-aria/selection": { - "version": "3.22.0", - "resolved": "https://registry.npmjs.org/@react-aria/selection/-/selection-3.22.0.tgz", - "integrity": "sha512-XFOrK525HX2eeWeLZcZscUAs5qsuC1ZxsInDXMjvLeAaUPtQNEhUKHj3psDAl6XDU4VV1IJo0qCmFTVqTTMZSg==", + "version": "3.27.1", + "resolved": "https://registry.npmjs.org/@react-aria/selection/-/selection-3.27.1.tgz", + "integrity": "sha512-8WQ4AtWiBnk9UEeYkqpH12dd8KQW2aFbNZvM4sDfLtz7K7HWyY/MkqMe/snk9IcoSa7t4zr0bnoZJcWSGgn2PQ==", "license": "Apache-2.0", "dependencies": { - "@react-aria/focus": "^3.19.1", - "@react-aria/i18n": "^3.12.5", - "@react-aria/interactions": "^3.23.0", - "@react-aria/utils": "^3.27.0", - "@react-stately/selection": "^3.19.0", - "@react-types/shared": "^3.27.0", + "@react-aria/focus": "^3.21.4", + "@react-aria/i18n": "^3.12.15", + "@react-aria/interactions": "^3.27.0", + "@react-aria/utils": "^3.33.0", + "@react-stately/selection": "^3.20.8", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1634,13 +1993,13 @@ } }, "node_modules/@react-aria/separator": { - "version": "3.4.5", - "resolved": "https://registry.npmjs.org/@react-aria/separator/-/separator-3.4.5.tgz", - "integrity": "sha512-RQA9sKZdAEjP1Yrv0GpDdXgmXd56kXDE8atPDHEC0/A4lpYh/YFLfXcv1JW0Hlg4kBocdX2pB2INyDGhiD+yfw==", + "version": "3.4.15", + "resolved": "https://registry.npmjs.org/@react-aria/separator/-/separator-3.4.15.tgz", + "integrity": "sha512-A1aPQhCaE8XeelNJYPjHtA2uh921ROh8PNiZI4o62x80wcziRoctN5PAtNHJAx7VKvX66A8ZVGbOqb7iqS3J5Q==", "license": "Apache-2.0", "dependencies": { - "@react-aria/utils": "^3.27.0", - "@react-types/shared": "^3.27.0", + "@react-aria/utils": "^3.33.0", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1649,19 +2008,18 @@ } }, "node_modules/@react-aria/slider": { - "version": "3.7.15", - "resolved": "https://registry.npmjs.org/@react-aria/slider/-/slider-3.7.15.tgz", - "integrity": "sha512-v9tujsuvJYRX0vE/vMYBzTT9FXbzrLsjkOrouNq+UdBIr7wRjIWTHHM0j+khb2swyCWNTbdv6Ce316Zqx2qWFg==", + "version": "3.8.4", + "resolved": "https://registry.npmjs.org/@react-aria/slider/-/slider-3.8.4.tgz", + "integrity": "sha512-/FYCgK1qVqaz2VCDfR2x4BjyJ8lmWg1v8//+WIwKdIu4cz0KUs+U3yx0w1vp676RoERp3OEvkT3tb+/jHQ1hjA==", "license": "Apache-2.0", "dependencies": { - "@react-aria/focus": "^3.19.1", - "@react-aria/i18n": "^3.12.5", - "@react-aria/interactions": "^3.23.0", - "@react-aria/label": "^3.7.14", - "@react-aria/utils": "^3.27.0", - "@react-stately/slider": "^3.6.1", - "@react-types/shared": "^3.27.0", - "@react-types/slider": "^3.7.8", + "@react-aria/i18n": "^3.12.15", + "@react-aria/interactions": "^3.27.0", + "@react-aria/label": "^3.7.24", + "@react-aria/utils": "^3.33.0", + "@react-stately/slider": "^3.7.4", + "@react-types/shared": "^3.33.0", + "@react-types/slider": "^3.8.3", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1670,16 +2028,16 @@ } }, "node_modules/@react-aria/spinbutton": { - "version": "3.6.11", - "resolved": "https://registry.npmjs.org/@react-aria/spinbutton/-/spinbutton-3.6.11.tgz", - "integrity": "sha512-RM+gYS9tf9Wb+GegV18n4ArK3NBKgcsak7Nx1CkEgX9BjJ0yayWUHdfEjRRvxGXl+1z1n84cJVkZ6FUlWOWEZA==", + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@react-aria/spinbutton/-/spinbutton-3.7.1.tgz", + "integrity": "sha512-Nisah6yzxOC6983u/5ck0w+OQoa3sRKmpDvWpTEX0g2+ZIABOl8ttdSd65XKtxXmXHdK8X1zmrfeGOBfBR3sKA==", "license": "Apache-2.0", "dependencies": { - "@react-aria/i18n": "^3.12.5", - "@react-aria/live-announcer": "^3.4.1", - "@react-aria/utils": "^3.27.0", - "@react-types/button": "^3.10.2", - "@react-types/shared": "^3.27.0", + "@react-aria/i18n": "^3.12.15", + "@react-aria/live-announcer": "^3.4.4", + "@react-aria/utils": "^3.33.0", + "@react-types/button": "^3.15.0", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1688,9 +2046,9 @@ } }, "node_modules/@react-aria/ssr": { - "version": "3.9.7", - "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.7.tgz", - "integrity": "sha512-GQygZaGlmYjmYM+tiNBA5C6acmiDWF52Nqd40bBp0Znk4M4hP+LTmI0lpI1BuKMw45T8RIhrAsICIfKwZvi2Gg==", + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.10.tgz", + "integrity": "sha512-hvTm77Pf+pMBhuBm760Li0BVIO38jv1IBws1xFm1NoL26PU+fe+FMW5+VZWyANR6nYL65joaJKZqOdTQMkO9IQ==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0" @@ -1703,41 +2061,42 @@ } }, "node_modules/@react-aria/switch": { - "version": "3.6.11", - "resolved": "https://registry.npmjs.org/@react-aria/switch/-/switch-3.6.11.tgz", - "integrity": "sha512-paYCpH+oeL+8rgQK+cBJ+IaZ1sXSh3+50WPlg2LvLBta0QVfQhPR4juPvfXRpfHHhCjFBgF4/RGbV8q5zpl3vA==", + "version": "3.7.10", + "resolved": "https://registry.npmjs.org/@react-aria/switch/-/switch-3.7.10.tgz", + "integrity": "sha512-j7nrYnqX6H9J8GuqD0kdMECUozeqxeG19A2nsvfaTx3//Q7RhgIR9fqhQdVHW/wgraTlEHNH6AhDzmomBg0TNw==", "license": "Apache-2.0", "dependencies": { - "@react-aria/toggle": "^3.10.11", - "@react-stately/toggle": "^3.8.1", - "@react-types/shared": "^3.27.0", - "@react-types/switch": "^3.5.8", + "@react-aria/toggle": "^3.12.4", + "@react-stately/toggle": "^3.9.4", + "@react-types/shared": "^3.33.0", + "@react-types/switch": "^3.5.16", "@swc/helpers": "^0.5.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-aria/table": { - "version": "3.16.1", - "resolved": "https://registry.npmjs.org/@react-aria/table/-/table-3.16.1.tgz", - "integrity": "sha512-T28TIGnKnPBunyErDBmm5jUX7AyzT7NVWBo9pDSt9wUuEnz0rVNd7p9sjmP2+u7I645feGG9klcdpCvFeqrk8A==", + "version": "3.17.10", + "resolved": "https://registry.npmjs.org/@react-aria/table/-/table-3.17.10.tgz", + "integrity": "sha512-xdEeyOzuETkOfAHhZrX7HOIwMUsCUr4rbPvHqdcNqg7Ngla2ck9iulZNAyvOPfFwELuBEd2rz1I9TYRQ2OzSQQ==", "license": "Apache-2.0", "dependencies": { - "@react-aria/focus": "^3.19.1", - "@react-aria/grid": "^3.11.1", - "@react-aria/i18n": "^3.12.5", - "@react-aria/interactions": "^3.23.0", - "@react-aria/live-announcer": "^3.4.1", - "@react-aria/utils": "^3.27.0", - "@react-aria/visually-hidden": "^3.8.19", - "@react-stately/collections": "^3.12.1", - "@react-stately/flags": "^3.0.5", - "@react-stately/table": "^3.13.1", - "@react-types/checkbox": "^3.9.1", - "@react-types/grid": "^3.2.11", - "@react-types/shared": "^3.27.0", - "@react-types/table": "^3.10.4", + "@react-aria/focus": "^3.21.4", + "@react-aria/grid": "^3.14.7", + "@react-aria/i18n": "^3.12.15", + "@react-aria/interactions": "^3.27.0", + "@react-aria/live-announcer": "^3.4.4", + "@react-aria/utils": "^3.33.0", + "@react-aria/visually-hidden": "^3.8.30", + "@react-stately/collections": "^3.12.9", + "@react-stately/flags": "^3.1.2", + "@react-stately/table": "^3.15.3", + "@react-types/checkbox": "^3.10.3", + "@react-types/grid": "^3.3.7", + "@react-types/shared": "^3.33.0", + "@react-types/table": "^3.13.5", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1746,18 +2105,18 @@ } }, "node_modules/@react-aria/tabs": { - "version": "3.9.9", - "resolved": "https://registry.npmjs.org/@react-aria/tabs/-/tabs-3.9.9.tgz", - "integrity": "sha512-oXPtANs16xu6MdMGLHjGV/2Zupvyp9CJEt7ORPLv5xAzSY5hSjuQHJLZ0te3Lh/KSG5/0o3RW/W5yEqo7pBQQQ==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@react-aria/tabs/-/tabs-3.11.0.tgz", + "integrity": "sha512-9Gwo118GHrMXSyteCZL1L/LHLVlGSYkhGgiTL3e/UgnYjHfEfDJVTkV2JikuE2O/4uig52gQRlq5E99axLeE9Q==", "license": "Apache-2.0", "dependencies": { - "@react-aria/focus": "^3.19.1", - "@react-aria/i18n": "^3.12.5", - "@react-aria/selection": "^3.22.0", - "@react-aria/utils": "^3.27.0", - "@react-stately/tabs": "^3.7.1", - "@react-types/shared": "^3.27.0", - "@react-types/tabs": "^3.3.12", + "@react-aria/focus": "^3.21.4", + "@react-aria/i18n": "^3.12.15", + "@react-aria/selection": "^3.27.1", + "@react-aria/utils": "^3.33.0", + "@react-stately/tabs": "^3.8.8", + "@react-types/shared": "^3.33.0", + "@react-types/tabs": "^3.3.21", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1766,20 +2125,20 @@ } }, "node_modules/@react-aria/tag": { - "version": "3.4.9", - "resolved": "https://registry.npmjs.org/@react-aria/tag/-/tag-3.4.9.tgz", - "integrity": "sha512-Vnps+zk8vYyjevv2Bc6vc9kSp9HFLKrKUDmrWMc0DfseypwJMc3Ya6F965ZVTjF9nuWrojNmvgusNu7qyXFShQ==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/@react-aria/tag/-/tag-3.8.0.tgz", + "integrity": "sha512-sTV6uRKFIFU1aljKb0QjM6fPPnzBuitrbkkCUZCJ0w0RIX1JinZPh96NknNtjFwWmqoROjVNCq51EUd0Hh2SQw==", "license": "Apache-2.0", "dependencies": { - "@react-aria/gridlist": "^3.10.1", - "@react-aria/i18n": "^3.12.5", - "@react-aria/interactions": "^3.23.0", - "@react-aria/label": "^3.7.14", - "@react-aria/selection": "^3.22.0", - "@react-aria/utils": "^3.27.0", - "@react-stately/list": "^3.11.2", - "@react-types/button": "^3.10.2", - "@react-types/shared": "^3.27.0", + "@react-aria/gridlist": "^3.14.3", + "@react-aria/i18n": "^3.12.15", + "@react-aria/interactions": "^3.27.0", + "@react-aria/label": "^3.7.24", + "@react-aria/selection": "^3.27.1", + "@react-aria/utils": "^3.33.0", + "@react-stately/list": "^3.13.3", + "@react-types/button": "^3.15.0", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1788,19 +2147,39 @@ } }, "node_modules/@react-aria/textfield": { - "version": "3.16.0", - "resolved": "https://registry.npmjs.org/@react-aria/textfield/-/textfield-3.16.0.tgz", - "integrity": "sha512-53RVpMeMDN/QoabqnYZ1lxTh1xTQ3IBYQARuayq5EGGMafyxoFHzttxUdSqkZGK/+zdSF2GfmjOYJVm2nDKuDQ==", + "version": "3.18.4", + "resolved": "https://registry.npmjs.org/@react-aria/textfield/-/textfield-3.18.4.tgz", + "integrity": "sha512-ts3Vdy2qNOzjCVeO+4RH8FSgTYN2USAMcYFeGbHOriCukVOrvgRsqcDniW7xaT60LgFdlWMJsCusvltSIyo6xw==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/form": "^3.1.4", + "@react-aria/interactions": "^3.27.0", + "@react-aria/label": "^3.7.24", + "@react-aria/utils": "^3.33.0", + "@react-stately/form": "^3.2.3", + "@react-stately/utils": "^3.11.0", + "@react-types/shared": "^3.33.0", + "@react-types/textfield": "^3.12.7", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/toast": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@react-aria/toast/-/toast-3.0.10.tgz", + "integrity": "sha512-irW5Cr4msbPo4A4ysjT70MDJbpGCe1h9SkFgdYXBPA4Xbi4jRT7TiEZeIS1I7Hsvp6shAK1Ld/m6NBS0b/gyzg==", "license": "Apache-2.0", "dependencies": { - "@react-aria/focus": "^3.19.1", - "@react-aria/form": "^3.0.12", - "@react-aria/label": "^3.7.14", - "@react-aria/utils": "^3.27.0", - "@react-stately/form": "^3.1.1", - "@react-stately/utils": "^3.10.5", - "@react-types/shared": "^3.27.0", - "@react-types/textfield": "^3.11.0", + "@react-aria/i18n": "^3.12.15", + "@react-aria/interactions": "^3.27.0", + "@react-aria/landmark": "^3.0.9", + "@react-aria/utils": "^3.33.0", + "@react-stately/toast": "^3.1.3", + "@react-types/button": "^3.15.0", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1809,17 +2188,16 @@ } }, "node_modules/@react-aria/toggle": { - "version": "3.10.11", - "resolved": "https://registry.npmjs.org/@react-aria/toggle/-/toggle-3.10.11.tgz", - "integrity": "sha512-J3jO3KJiUbaYVDEpeXSBwqcyKxpi9OreiHRGiaxb6VwB+FWCj7Gb2WKajByXNyfs8jc6kX9VUFaXa7jze60oEQ==", + "version": "3.12.4", + "resolved": "https://registry.npmjs.org/@react-aria/toggle/-/toggle-3.12.4.tgz", + "integrity": "sha512-yVcl8kEFLsV47aCA22EMPcd/KWoYqPIPSzoKjRD/iWmxcP6iGzSxDjdUgMQojNGY8Q6wL8lUxfRqKBjvl/uezQ==", "license": "Apache-2.0", "dependencies": { - "@react-aria/focus": "^3.19.1", - "@react-aria/interactions": "^3.23.0", - "@react-aria/utils": "^3.27.0", - "@react-stately/toggle": "^3.8.1", - "@react-types/checkbox": "^3.9.1", - "@react-types/shared": "^3.27.0", + "@react-aria/interactions": "^3.27.0", + "@react-aria/utils": "^3.33.0", + "@react-stately/toggle": "^3.9.4", + "@react-types/checkbox": "^3.10.3", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1828,15 +2206,15 @@ } }, "node_modules/@react-aria/toolbar": { - "version": "3.0.0-beta.12", - "resolved": "https://registry.npmjs.org/@react-aria/toolbar/-/toolbar-3.0.0-beta.12.tgz", - "integrity": "sha512-a+Be27BtM2lzEdTzm19FikPbitfW65g/JZln3kyAvgpswhU6Ljl8lztaVw4ixjG4H0nqnKvVggMy4AlWwDUaVQ==", + "version": "3.0.0-beta.23", + "resolved": "https://registry.npmjs.org/@react-aria/toolbar/-/toolbar-3.0.0-beta.23.tgz", + "integrity": "sha512-FzvNf2hWtjEwk8F2MBf4qSs6AAR/p2WFSws6kJ4f0SrWXl4wR9VDEwBEUQcIPbWCK2aUsyOjubCh55Cl4t3MoQ==", "license": "Apache-2.0", "dependencies": { - "@react-aria/focus": "^3.19.1", - "@react-aria/i18n": "^3.12.5", - "@react-aria/utils": "^3.27.0", - "@react-types/shared": "^3.27.0", + "@react-aria/focus": "^3.21.4", + "@react-aria/i18n": "^3.12.15", + "@react-aria/utils": "^3.33.0", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1845,17 +2223,36 @@ } }, "node_modules/@react-aria/tooltip": { - "version": "3.7.11", - "resolved": "https://registry.npmjs.org/@react-aria/tooltip/-/tooltip-3.7.11.tgz", - "integrity": "sha512-mhZgAWUj7bUWipDeJXaVPZdqnzoBCd/uaEbdafnvgETmov1udVqPTh9w4ZKX2Oh1wa2+OdLFrBOk+8vC6QbWag==", + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/@react-aria/tooltip/-/tooltip-3.9.1.tgz", + "integrity": "sha512-mvEhqpvF4v/wj9zw3a8bsAEnySutGbxKXXt39s6WvF6dkVfaXfsmV9ahuMCHH//UGh/yidZGLrXX4YVdrgS8lA==", "license": "Apache-2.0", "dependencies": { - "@react-aria/focus": "^3.19.1", - "@react-aria/interactions": "^3.23.0", - "@react-aria/utils": "^3.27.0", - "@react-stately/tooltip": "^3.5.1", - "@react-types/shared": "^3.27.0", - "@react-types/tooltip": "^3.4.14", + "@react-aria/interactions": "^3.27.0", + "@react-aria/utils": "^3.33.0", + "@react-stately/tooltip": "^3.5.10", + "@react-types/shared": "^3.33.0", + "@react-types/tooltip": "^3.5.1", + "@swc/helpers": "^0.5.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, + "node_modules/@react-aria/tree": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@react-aria/tree/-/tree-3.1.6.tgz", + "integrity": "sha512-igLX+OQrbXCBLrtPWgUevU0iDrgTSAJh1ncHoPzfD/YDcyTDLqKdy2nZhNbJ/IdHCwTyzIknhFJ700K20Ymw9A==", + "license": "Apache-2.0", + "dependencies": { + "@react-aria/gridlist": "^3.14.3", + "@react-aria/i18n": "^3.12.15", + "@react-aria/selection": "^3.27.1", + "@react-aria/utils": "^3.33.0", + "@react-stately/tree": "^3.9.5", + "@react-types/button": "^3.15.0", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1864,14 +2261,15 @@ } }, "node_modules/@react-aria/utils": { - "version": "3.27.0", - "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.27.0.tgz", - "integrity": "sha512-p681OtApnKOdbeN8ITfnnYqfdHS0z7GE+4l8EXlfLnr70Rp/9xicBO6d2rU+V/B3JujDw2gPWxYKEnEeh0CGCw==", + "version": "3.33.0", + "resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.33.0.tgz", + "integrity": "sha512-yvz7CMH8d2VjwbSa5nGXqjU031tYhD8ddax95VzJsHSPyqHDEGfxul8RkhGV6oO7bVqZxVs6xY66NIgae+FHjw==", "license": "Apache-2.0", "dependencies": { - "@react-aria/ssr": "^3.9.7", - "@react-stately/utils": "^3.10.5", - "@react-types/shared": "^3.27.0", + "@react-aria/ssr": "^3.9.10", + "@react-stately/flags": "^3.1.2", + "@react-stately/utils": "^3.11.0", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0", "clsx": "^2.0.0" }, @@ -1881,14 +2279,14 @@ } }, "node_modules/@react-aria/visually-hidden": { - "version": "3.8.19", - "resolved": "https://registry.npmjs.org/@react-aria/visually-hidden/-/visually-hidden-3.8.19.tgz", - "integrity": "sha512-MZgCCyQ3sdG94J5iJz7I7Ai3IxoN0U5d/+EaUnA1mfK7jf2fSYQBqi6Eyp8sWUYzBTLw4giXB5h0RGAnWzk9hA==", + "version": "3.8.30", + "resolved": "https://registry.npmjs.org/@react-aria/visually-hidden/-/visually-hidden-3.8.30.tgz", + "integrity": "sha512-iY44USEU8sJy0NOJ/sTDn3YlspbhHuVG3nx2YYrzfmxbS3i+lNwkCfG8kJ77dtmbuDLIdBGKENjGkbcwz3kiJg==", "license": "Apache-2.0", "dependencies": { - "@react-aria/interactions": "^3.23.0", - "@react-aria/utils": "^3.27.0", - "@react-types/shared": "^3.27.0", + "@react-aria/interactions": "^3.27.0", + "@react-aria/utils": "^3.33.0", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1897,15 +2295,15 @@ } }, "node_modules/@react-stately/calendar": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@react-stately/calendar/-/calendar-3.7.0.tgz", - "integrity": "sha512-N15zKubP2S7eWfPSJjKVlmJA7YpWzrIGx52BFhwLSQAZcV+OPcMgvOs71WtB7PLwl6DUYQGsgc0B3tcHzzvdvQ==", + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@react-stately/calendar/-/calendar-3.9.2.tgz", + "integrity": "sha512-AQj8/izwb7eY+KFqKcMLI2ygvnbAIwLuQG5KPHgJsMygFqnN4yzXKz5orGqVJnxEXLKiLPteVztx7b5EQobrtw==", "license": "Apache-2.0", "dependencies": { - "@internationalized/date": "^3.7.0", - "@react-stately/utils": "^3.10.5", - "@react-types/calendar": "^3.6.0", - "@react-types/shared": "^3.27.0", + "@internationalized/date": "^3.11.0", + "@react-stately/utils": "^3.11.0", + "@react-types/calendar": "^3.8.2", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1913,15 +2311,15 @@ } }, "node_modules/@react-stately/checkbox": { - "version": "3.6.11", - "resolved": "https://registry.npmjs.org/@react-stately/checkbox/-/checkbox-3.6.11.tgz", - "integrity": "sha512-jApdBis+Q1sXLivg+f7krcVaP/AMMMiQcVqcz5gwxlweQN+dRZ/NpL0BYaDOuGc26Mp0lcuVaET3jIZeHwtyxA==", + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@react-stately/checkbox/-/checkbox-3.7.4.tgz", + "integrity": "sha512-oXHMkK22CWLcmNlunDuu4p52QXYmkpx6es9AjWx/xlh3XLZdJzo/5SANioOH1QvBtwPA/c2KQy+ZBqC21NtMHw==", "license": "Apache-2.0", "dependencies": { - "@react-stately/form": "^3.1.1", - "@react-stately/utils": "^3.10.5", - "@react-types/checkbox": "^3.9.1", - "@react-types/shared": "^3.27.0", + "@react-stately/form": "^3.2.3", + "@react-stately/utils": "^3.11.0", + "@react-types/checkbox": "^3.10.3", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1929,12 +2327,12 @@ } }, "node_modules/@react-stately/collections": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/@react-stately/collections/-/collections-3.12.1.tgz", - "integrity": "sha512-8QmFBL7f+P64dEP4o35pYH61/lP0T/ziSdZAvNMrCqaM+fXcMfUp2yu1E63kADVX7WRDsFJWE3CVMeqirPH6Xg==", + "version": "3.12.9", + "resolved": "https://registry.npmjs.org/@react-stately/collections/-/collections-3.12.9.tgz", + "integrity": "sha512-2jywPMhVgMOh0XtutxPqIxFCIiLOnL/GXIrRKoBEo8M3Q24NoMRBavUrn9RTvjqNnec1i/8w1/8sq8cmCKEohA==", "license": "Apache-2.0", "dependencies": { - "@react-types/shared": "^3.27.0", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1942,19 +2340,19 @@ } }, "node_modules/@react-stately/color": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/@react-stately/color/-/color-3.8.2.tgz", - "integrity": "sha512-GXwLmv1Eos2OwOiRsGFrXBKx8+uZh2q0qzLZEVYrWsedNhIdTm7nnpwO68nCYZPHkqhv6rhhVSlOOFmDLY++ow==", + "version": "3.9.4", + "resolved": "https://registry.npmjs.org/@react-stately/color/-/color-3.9.4.tgz", + "integrity": "sha512-SprAP5STMg6K0jq+A3UoimsvvTCIGItUtWurS/lDRoQJYajFR8IUdz+mekU/GaXzvFhMN32dijOtFcfxnA4cfA==", "license": "Apache-2.0", "dependencies": { - "@internationalized/number": "^3.6.0", - "@internationalized/string": "^3.2.5", - "@react-stately/form": "^3.1.1", - "@react-stately/numberfield": "^3.9.9", - "@react-stately/slider": "^3.6.1", - "@react-stately/utils": "^3.10.5", - "@react-types/color": "^3.0.2", - "@react-types/shared": "^3.27.0", + "@internationalized/number": "^3.6.5", + "@internationalized/string": "^3.2.7", + "@react-stately/form": "^3.2.3", + "@react-stately/numberfield": "^3.10.4", + "@react-stately/slider": "^3.7.4", + "@react-stately/utils": "^3.11.0", + "@react-types/color": "^3.1.3", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1962,19 +2360,18 @@ } }, "node_modules/@react-stately/combobox": { - "version": "3.10.2", - "resolved": "https://registry.npmjs.org/@react-stately/combobox/-/combobox-3.10.2.tgz", - "integrity": "sha512-uT642Dool4tQBh+8UQjlJnTisrJVtg3LqmiP/HqLQ4O3pW0O+ImbG+2r6c9dUzlAnH4kEfmEwCp9dxkBkmFWsg==", + "version": "3.12.2", + "resolved": "https://registry.npmjs.org/@react-stately/combobox/-/combobox-3.12.2.tgz", + "integrity": "sha512-h4YRmzA+s3aMwUrXm6jyWLN0BWWXUNiodArB1wC24xNdeI7S8O3mxz6G2r3Ne8AE02FXmZXs9SD30Mx5vVVuqQ==", "license": "Apache-2.0", "dependencies": { - "@react-stately/collections": "^3.12.1", - "@react-stately/form": "^3.1.1", - "@react-stately/list": "^3.11.2", - "@react-stately/overlays": "^3.6.13", - "@react-stately/select": "^3.6.10", - "@react-stately/utils": "^3.10.5", - "@react-types/combobox": "^3.13.2", - "@react-types/shared": "^3.27.0", + "@react-stately/collections": "^3.12.9", + "@react-stately/form": "^3.2.3", + "@react-stately/list": "^3.13.3", + "@react-stately/overlays": "^3.6.22", + "@react-stately/utils": "^3.11.0", + "@react-types/combobox": "^3.13.11", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -1982,18 +2379,19 @@ } }, "node_modules/@react-stately/datepicker": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/@react-stately/datepicker/-/datepicker-3.12.0.tgz", - "integrity": "sha512-AfJEP36d+QgQ30GfacXtYdGsJvqY2yuCJ+JrjHct+m1nYuTkMvMMnhwNBFasgDJPLCDyHzyANlWkl2kQGfsBFw==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/@react-stately/datepicker/-/datepicker-3.16.0.tgz", + "integrity": "sha512-mYtzKXufFVivrHjmxys3ryJFMPIQNhVqaSItmGnWv3ehxw+0HKBrROf3BFiEN4zP20euoP149ZaR4uNx90kMYw==", "license": "Apache-2.0", "dependencies": { - "@internationalized/date": "^3.7.0", - "@internationalized/string": "^3.2.5", - "@react-stately/form": "^3.1.1", - "@react-stately/overlays": "^3.6.13", - "@react-stately/utils": "^3.10.5", - "@react-types/datepicker": "^3.10.0", - "@react-types/shared": "^3.27.0", + "@internationalized/date": "^3.11.0", + "@internationalized/number": "^3.6.5", + "@internationalized/string": "^3.2.7", + "@react-stately/form": "^3.2.3", + "@react-stately/overlays": "^3.6.22", + "@react-stately/utils": "^3.11.0", + "@react-types/datepicker": "^3.13.4", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -2001,13 +2399,13 @@ } }, "node_modules/@react-stately/disclosure": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@react-stately/disclosure/-/disclosure-3.0.1.tgz", - "integrity": "sha512-afpNy5b0UcqRGjU/W5OD0xkx4PbymvhMrgQZ4o4OdtDVMMvr9T5UqMF8/j3J591DxgQfXM872tJu0kotqT0L6Q==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@react-stately/disclosure/-/disclosure-3.0.10.tgz", + "integrity": "sha512-nUistLYMjBDy+yaS5H0y0Dwfcjr12zpIh7vjhQXF4wxIh3D08NRvV1NCQ0LV+IsMej/qoPJvKS4EnXHxBI3GmQ==", "license": "Apache-2.0", "dependencies": { - "@react-stately/utils": "^3.10.5", - "@react-types/shared": "^3.27.0", + "@react-stately/utils": "^3.11.0", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -2015,13 +2413,13 @@ } }, "node_modules/@react-stately/dnd": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@react-stately/dnd/-/dnd-3.5.1.tgz", - "integrity": "sha512-N18wt6fka9ngJJqxfAzmdtyrk9whAnqWUxZn22CatjNQsqukI4a6KRYwZTXM9x/wm7KamhVOp+GBl85zM8GLdA==", + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/@react-stately/dnd/-/dnd-3.7.3.tgz", + "integrity": "sha512-yBtzAimyYvJWnzP80Scx7l559+43TVSyjaMpUR6/s2IjqD3XoPKgPsv7KaFUmygBTkCBGBFJn404rYgMCOsu3g==", "license": "Apache-2.0", "dependencies": { - "@react-stately/selection": "^3.19.0", - "@react-types/shared": "^3.27.0", + "@react-stately/selection": "^3.20.8", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -2029,21 +2427,21 @@ } }, "node_modules/@react-stately/flags": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@react-stately/flags/-/flags-3.0.5.tgz", - "integrity": "sha512-6wks4csxUwPCp23LgJSnkBRhrWpd9jGd64DjcCTNB2AHIFu7Ab1W59pJpUL6TW7uAxVxdNKjgn6D1hlBy8qWsA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@react-stately/flags/-/flags-3.1.2.tgz", + "integrity": "sha512-2HjFcZx1MyQXoPqcBGALwWWmgFVUk2TuKVIQxCbRq7fPyWXIl6VHcakCLurdtYC2Iks7zizvz0Idv48MQ38DWg==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0" } }, "node_modules/@react-stately/form": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@react-stately/form/-/form-3.1.1.tgz", - "integrity": "sha512-qavrz5X5Mdf/Q1v/QJRxc0F8UTNEyRCNSM1we/nnF7GV64+aYSDLOtaRGmzq+09RSwo1c8ZYnIkK5CnwsPhTsQ==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@react-stately/form/-/form-3.2.3.tgz", + "integrity": "sha512-NPvjJtns1Pq9uvqeRJCf8HIdVmOm2ARLYQ2F/sqXj1w5IChJ4oWL4Xzvj29/zBitgE1vVjDhnrnwSfNlHZGX0g==", "license": "Apache-2.0", "dependencies": { - "@react-types/shared": "^3.27.0", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -2051,15 +2449,15 @@ } }, "node_modules/@react-stately/grid": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@react-stately/grid/-/grid-3.10.1.tgz", - "integrity": "sha512-MOIy//AdxZxIXIzvWSKpvMvaPEMZGQNj+/cOsElHepv/Veh0psNURZMh2TP6Mr0+MnDTZbX+5XIeinGkWYO3JQ==", + "version": "3.11.8", + "resolved": "https://registry.npmjs.org/@react-stately/grid/-/grid-3.11.8.tgz", + "integrity": "sha512-tCabR5U7ype+uEElS5Chv5n6ntUv3drXa9DwebjO05cFevUmjTkEfYPJWixpgX4UlCCvjdUFgzeQlJF+gCiozg==", "license": "Apache-2.0", "dependencies": { - "@react-stately/collections": "^3.12.1", - "@react-stately/selection": "^3.19.0", - "@react-types/grid": "^3.2.11", - "@react-types/shared": "^3.27.0", + "@react-stately/collections": "^3.12.9", + "@react-stately/selection": "^3.20.8", + "@react-types/grid": "^3.3.7", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -2067,15 +2465,15 @@ } }, "node_modules/@react-stately/list": { - "version": "3.11.2", - "resolved": "https://registry.npmjs.org/@react-stately/list/-/list-3.11.2.tgz", - "integrity": "sha512-eU2tY3aWj0SEeC7lH9AQoeAB4LL9mwS54FvTgHHoOgc1ZIwRJUaZoiuETyWQe98AL8KMgR1nrnDJ1I+CcT1Y7g==", + "version": "3.13.3", + "resolved": "https://registry.npmjs.org/@react-stately/list/-/list-3.13.3.tgz", + "integrity": "sha512-xN0v7rzhIKshhcshOzx+ZgVngXnGCtMPRdhoDLGaHzQy5YfxvKBMNLCnr5Lm4T1U/kIvHbyzxmr5uwmH8WxoIg==", "license": "Apache-2.0", "dependencies": { - "@react-stately/collections": "^3.12.1", - "@react-stately/selection": "^3.19.0", - "@react-stately/utils": "^3.10.5", - "@react-types/shared": "^3.27.0", + "@react-stately/collections": "^3.12.9", + "@react-stately/selection": "^3.20.8", + "@react-stately/utils": "^3.11.0", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -2083,14 +2481,14 @@ } }, "node_modules/@react-stately/menu": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@react-stately/menu/-/menu-3.9.1.tgz", - "integrity": "sha512-WRjGGImhQlQaer/hhahGytwd1BDq3fjpTkY/04wv3cQJPJR6lkVI5nSvGFMHfCaErsA1bNyB8/T9Y5F5u4u9ng==", + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/@react-stately/menu/-/menu-3.9.10.tgz", + "integrity": "sha512-dY9FzjQ+6iNInVujZPyMklDGoSbaoO0yguUnALAY+yfkPAyStEElfm4aXZgRfNKOTNHe9E34oV7qefSYsclvTg==", "license": "Apache-2.0", "dependencies": { - "@react-stately/overlays": "^3.6.13", - "@react-types/menu": "^3.9.14", - "@react-types/shared": "^3.27.0", + "@react-stately/overlays": "^3.6.22", + "@react-types/menu": "^3.10.6", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -2098,15 +2496,15 @@ } }, "node_modules/@react-stately/numberfield": { - "version": "3.9.9", - "resolved": "https://registry.npmjs.org/@react-stately/numberfield/-/numberfield-3.9.9.tgz", - "integrity": "sha512-hZsLiGGHTHmffjFymbH1qVmA633rU2GNjMFQTuSsN4lqqaP8fgxngd5pPCoTCUFEkUgWjdHenw+ZFByw8lIE+g==", + "version": "3.10.4", + "resolved": "https://registry.npmjs.org/@react-stately/numberfield/-/numberfield-3.10.4.tgz", + "integrity": "sha512-EniHHwXOw/Ta0x5j61OvldDAvLoi/8xOo//bzrqwnDvf2/1IKGFMD9CHs7HYhQw+9oNl3Q2V1meOTNPc4PvoMQ==", "license": "Apache-2.0", "dependencies": { - "@internationalized/number": "^3.6.0", - "@react-stately/form": "^3.1.1", - "@react-stately/utils": "^3.10.5", - "@react-types/numberfield": "^3.8.8", + "@internationalized/number": "^3.6.5", + "@react-stately/form": "^3.2.3", + "@react-stately/utils": "^3.11.0", + "@react-types/numberfield": "^3.8.17", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -2114,13 +2512,13 @@ } }, "node_modules/@react-stately/overlays": { - "version": "3.6.13", - "resolved": "https://registry.npmjs.org/@react-stately/overlays/-/overlays-3.6.13.tgz", - "integrity": "sha512-WsU85Gf/b+HbWsnnYw7P/Ila3wD+C37Uk/WbU4/fHgJ26IEOWsPE6wlul8j54NZ1PnLNhV9Fn+Kffi+PaJMQXQ==", + "version": "3.6.22", + "resolved": "https://registry.npmjs.org/@react-stately/overlays/-/overlays-3.6.22.tgz", + "integrity": "sha512-sWBnuy5dqVp8d+1e+ABTRVB3YBcOW86/90pF5PWY44au3bUFXVSUBO2QMdR/6JtojDoPRmrjufonI19/Zs/20w==", "license": "Apache-2.0", "dependencies": { - "@react-stately/utils": "^3.10.5", - "@react-types/overlays": "^3.8.12", + "@react-stately/utils": "^3.11.0", + "@react-types/overlays": "^3.9.3", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -2128,15 +2526,15 @@ } }, "node_modules/@react-stately/radio": { - "version": "3.10.10", - "resolved": "https://registry.npmjs.org/@react-stately/radio/-/radio-3.10.10.tgz", - "integrity": "sha512-9x3bpq87uV8iYA4NaioTTWjriQSlSdp+Huqlxll0T3W3okpyraTTejE91PbIoRTUmL5qByIh2WzxYmr4QdBgAA==", + "version": "3.11.4", + "resolved": "https://registry.npmjs.org/@react-stately/radio/-/radio-3.11.4.tgz", + "integrity": "sha512-3svsW5VxJA5/p1vO+Qlxv+7Jq9g7f4rqX9Rbqdfd+pH7ykHaV0CUKkSRMaWfcY8Vgaf2xmcc6dvusPRqKX8T1A==", "license": "Apache-2.0", "dependencies": { - "@react-stately/form": "^3.1.1", - "@react-stately/utils": "^3.10.5", - "@react-types/radio": "^3.8.6", - "@react-types/shared": "^3.27.0", + "@react-stately/form": "^3.2.3", + "@react-stately/utils": "^3.11.0", + "@react-types/radio": "^3.9.3", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -2144,13 +2542,13 @@ } }, "node_modules/@react-stately/searchfield": { - "version": "3.5.9", - "resolved": "https://registry.npmjs.org/@react-stately/searchfield/-/searchfield-3.5.9.tgz", - "integrity": "sha512-7/aO/oLJ4czKEji0taI/lbHKqPJRag9p3YmRaZ4yqjIMpKxzmJCWQcov5lzWeFhG/1hINKndYlxFnVIKV/urpg==", + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@react-stately/searchfield/-/searchfield-3.5.18.tgz", + "integrity": "sha512-C3/1wOON5oK0QBljj0vSbHm/IWgd29NxB+7zT1JjZcxtbcFxCj4HOxKdnPCT/d8Pojb0YS26QgKzatLZ0NnhgQ==", "license": "Apache-2.0", "dependencies": { - "@react-stately/utils": "^3.10.5", - "@react-types/searchfield": "^3.5.11", + "@react-stately/utils": "^3.11.0", + "@react-types/searchfield": "^3.6.7", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -2158,16 +2556,17 @@ } }, "node_modules/@react-stately/select": { - "version": "3.6.10", - "resolved": "https://registry.npmjs.org/@react-stately/select/-/select-3.6.10.tgz", - "integrity": "sha512-V7V0FCL9T+GzLjyfnJB6PUaKldFyT/8Rj6M+R9ura1A0O+s/FEOesy0pdMXFoL1l5zeUpGlCnhJrsI5HFWHfDw==", + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/@react-stately/select/-/select-3.9.1.tgz", + "integrity": "sha512-CJQRqv8Dg+0RRvcig3a2YfY6POJIscDINvidRF31yK6J72rsP01dY3ria9aJjizNDHR9Q5dWFp/z+ii0cOTWIQ==", "license": "Apache-2.0", "dependencies": { - "@react-stately/form": "^3.1.1", - "@react-stately/list": "^3.11.2", - "@react-stately/overlays": "^3.6.13", - "@react-types/select": "^3.9.9", - "@react-types/shared": "^3.27.0", + "@react-stately/form": "^3.2.3", + "@react-stately/list": "^3.13.3", + "@react-stately/overlays": "^3.6.22", + "@react-stately/utils": "^3.11.0", + "@react-types/select": "^3.12.1", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -2175,14 +2574,14 @@ } }, "node_modules/@react-stately/selection": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/@react-stately/selection/-/selection-3.19.0.tgz", - "integrity": "sha512-AvbUqnWjqVQC48RD39S9BpMKMLl55Zo5l/yx5JQFPl55cFwe9Tpku1KY0wzt3fXXiXWaqjDn/7Gkg1VJYy8esQ==", + "version": "3.20.8", + "resolved": "https://registry.npmjs.org/@react-stately/selection/-/selection-3.20.8.tgz", + "integrity": "sha512-V1kRN1NLW+i/3Xv+Q0pN9OzuM0zFEW9mdXOOOq7l+YL6hFjqIjttT2/q4KoyiNV3W0hfoRFSTQ7XCgqnqtwEng==", "license": "Apache-2.0", "dependencies": { - "@react-stately/collections": "^3.12.1", - "@react-stately/utils": "^3.10.5", - "@react-types/shared": "^3.27.0", + "@react-stately/collections": "^3.12.9", + "@react-stately/utils": "^3.11.0", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -2190,14 +2589,14 @@ } }, "node_modules/@react-stately/slider": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@react-stately/slider/-/slider-3.6.1.tgz", - "integrity": "sha512-8kij5O82Xe233vZZ6qNGqPXidnlNQiSnyF1q613c7ktFmzAyGjkIWVUapHi23T1fqm7H2Rs3RWlmwE9bo2KecA==", + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@react-stately/slider/-/slider-3.7.4.tgz", + "integrity": "sha512-cSOYSx2nsOQejMg6Ql0+GUpqAiPwRA5teYXUghNvuBDtVxnd4l2rnXs54Ww48tU43xf2+L3kkmMofThjABoEPw==", "license": "Apache-2.0", "dependencies": { - "@react-stately/utils": "^3.10.5", - "@react-types/shared": "^3.27.0", - "@react-types/slider": "^3.7.8", + "@react-stately/utils": "^3.11.0", + "@react-types/shared": "^3.33.0", + "@react-types/slider": "^3.8.3", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -2205,19 +2604,19 @@ } }, "node_modules/@react-stately/table": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/@react-stately/table/-/table-3.13.1.tgz", - "integrity": "sha512-Im8W+F8o9EhglY5kqRa3xcMGXl8zBi6W5phGpAjXb+UGDL1tBIlAcYj733bw8g/ITCnaSz9ubsmON0HekPd6Jg==", + "version": "3.15.3", + "resolved": "https://registry.npmjs.org/@react-stately/table/-/table-3.15.3.tgz", + "integrity": "sha512-W1wR0O/PmdD8hCUFIAelHICjUX/Ii6ZldPlH6EILr9olyGpoCaY7XmnyG7kii1aANuQGBeskjJdXvS6LX/gyDw==", "license": "Apache-2.0", "dependencies": { - "@react-stately/collections": "^3.12.1", - "@react-stately/flags": "^3.0.5", - "@react-stately/grid": "^3.10.1", - "@react-stately/selection": "^3.19.0", - "@react-stately/utils": "^3.10.5", - "@react-types/grid": "^3.2.11", - "@react-types/shared": "^3.27.0", - "@react-types/table": "^3.10.4", + "@react-stately/collections": "^3.12.9", + "@react-stately/flags": "^3.1.2", + "@react-stately/grid": "^3.11.8", + "@react-stately/selection": "^3.20.8", + "@react-stately/utils": "^3.11.0", + "@react-types/grid": "^3.3.7", + "@react-types/shared": "^3.33.0", + "@react-types/table": "^3.13.5", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -2225,29 +2624,42 @@ } }, "node_modules/@react-stately/tabs": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/@react-stately/tabs/-/tabs-3.7.1.tgz", - "integrity": "sha512-gr9ACyuWrYuc727h7WaHdmNw8yxVlUyQlguziR94MdeRtFGQnf3V6fNQG3kxyB77Ljko69tgDF7Nf6kfPUPAQQ==", + "version": "3.8.8", + "resolved": "https://registry.npmjs.org/@react-stately/tabs/-/tabs-3.8.8.tgz", + "integrity": "sha512-BZImWT+pHZitImRQkoL7jVhTtpGPSra1Rhh4pi8epzwogeqseEIEpuWpQebjQP74r1kfNi/iT2p5Qb31eWfh1Q==", "license": "Apache-2.0", "dependencies": { - "@react-stately/list": "^3.11.2", - "@react-types/shared": "^3.27.0", - "@react-types/tabs": "^3.3.12", + "@react-stately/list": "^3.13.3", + "@react-types/shared": "^3.33.0", + "@react-types/tabs": "^3.3.21", "@swc/helpers": "^0.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, + "node_modules/@react-stately/toast": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@react-stately/toast/-/toast-3.1.3.tgz", + "integrity": "sha512-mT9QJKmD523lqFpOp0VWZ6QHZENFK7HrodnNJDVc7g616s5GNmemdlkITV43fSY3tHeThCVvPu+Uzh7RvQ9mpQ==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0", + "use-sync-external-store": "^1.6.0" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" + } + }, "node_modules/@react-stately/toggle": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/@react-stately/toggle/-/toggle-3.8.1.tgz", - "integrity": "sha512-MVpe79ghVQiwLmVzIPhF/O/UJAUc9B+ZSylVTyJiEPi0cwhbkKGQv9thOF0ebkkRkace5lojASqUAYtSTZHQJA==", + "version": "3.9.4", + "resolved": "https://registry.npmjs.org/@react-stately/toggle/-/toggle-3.9.4.tgz", + "integrity": "sha512-tjWsshRJtHC+PI5NYMlnDlV/BTo1eWq6fmR6x1mXlQfKuKGTJRzhgJyaQ2mc5K+LkifD7fchOhfapHCrRlzwMg==", "license": "Apache-2.0", "dependencies": { - "@react-stately/utils": "^3.10.5", - "@react-types/checkbox": "^3.9.1", - "@react-types/shared": "^3.27.0", + "@react-stately/utils": "^3.11.0", + "@react-types/checkbox": "^3.10.3", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -2255,13 +2667,13 @@ } }, "node_modules/@react-stately/tooltip": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/@react-stately/tooltip/-/tooltip-3.5.1.tgz", - "integrity": "sha512-0aI3U5kB7Cop9OCW9/Bag04zkivFSdUcQgy/TWL4JtpXidVWmOha8txI1WySawFSjZhH83KIyPc+wKm1msfLMQ==", + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/@react-stately/tooltip/-/tooltip-3.5.10.tgz", + "integrity": "sha512-GauUdc6Of08Np2iUw4xx/DdgpvszS9CxJWYcRnNyAAGPLQrmniVrpJvb0EUKQTP9sUSci1SlmpvJh4SNZx26Bw==", "license": "Apache-2.0", "dependencies": { - "@react-stately/overlays": "^3.6.13", - "@react-types/tooltip": "^3.4.14", + "@react-stately/overlays": "^3.6.22", + "@react-types/tooltip": "^3.5.1", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -2269,15 +2681,15 @@ } }, "node_modules/@react-stately/tree": { - "version": "3.8.7", - "resolved": "https://registry.npmjs.org/@react-stately/tree/-/tree-3.8.7.tgz", - "integrity": "sha512-hpc3pyuXWeQV5ufQ02AeNQg/MYhnzZ4NOznlY5OOUoPzpLYiI3ZJubiY3Dot4jw5N/LR7CqvDLHmrHaJPmZlHg==", + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/@react-stately/tree/-/tree-3.9.5.tgz", + "integrity": "sha512-UpvBlzL/MpFdOepDg+cohI/zvw8DEVM8cXY/OZ8tKUXWpew1HpUglwnAI3ivm0L2k9laUIB9siW0g04ZWiH9Lg==", "license": "Apache-2.0", "dependencies": { - "@react-stately/collections": "^3.12.1", - "@react-stately/selection": "^3.19.0", - "@react-stately/utils": "^3.10.5", - "@react-types/shared": "^3.27.0", + "@react-stately/collections": "^3.12.9", + "@react-stately/selection": "^3.20.8", + "@react-stately/utils": "^3.11.0", + "@react-types/shared": "^3.33.0", "@swc/helpers": "^0.5.0" }, "peerDependencies": { @@ -2285,9 +2697,9 @@ } }, "node_modules/@react-stately/utils": { - "version": "3.10.5", - "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.5.tgz", - "integrity": "sha512-iMQSGcpaecghDIh3mZEpZfoFH3ExBwTtuBEcvZ2XnGzCgQjeYXcMdIUwAfVQLXFTdHUHGF6Gu6/dFrYsCzySBQ==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.11.0.tgz", + "integrity": "sha512-8LZpYowJ9eZmmYLpudbo/eclIRnbhWIJZ994ncmlKlouNzKohtM8qTC6B1w1pwUbiwGdUoyzLuQbeaIor5Dvcw==", "license": "Apache-2.0", "dependencies": { "@swc/helpers": "^0.5.0" @@ -2297,329 +2709,372 @@ } }, "node_modules/@react-types/breadcrumbs": { - "version": "3.7.10", - "resolved": "https://registry.npmjs.org/@react-types/breadcrumbs/-/breadcrumbs-3.7.10.tgz", - "integrity": "sha512-5HhRxkKHfAQBoyOYzyf4HT+24HgPE/C/QerxJLNNId303LXO03yeYrbvRqhYZSlD1ACLJW9OmpPpREcw5iSqgw==", + "version": "3.7.18", + "resolved": "https://registry.npmjs.org/@react-types/breadcrumbs/-/breadcrumbs-3.7.18.tgz", + "integrity": "sha512-zwltqx2XSELBRQeuCraxrdfT4fpIOVu6eQXsZ4RhWlsT7DLhzj3pUGkxdPDAMfYaVdyNBqc+nhiAnCwz6tUJ8A==", "license": "Apache-2.0", "dependencies": { - "@react-types/link": "^3.5.10", - "@react-types/shared": "^3.27.0" + "@react-types/link": "^3.6.6", + "@react-types/shared": "^3.33.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/button": { - "version": "3.10.2", - "resolved": "https://registry.npmjs.org/@react-types/button/-/button-3.10.2.tgz", - "integrity": "sha512-h8SB/BLoCgoBulCpyzaoZ+miKXrolK9XC48+n1dKJXT8g4gImrficurDW6+PRTQWaRai0Q0A6bu8UibZOU4syg==", + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/@react-types/button/-/button-3.15.0.tgz", + "integrity": "sha512-X/K2/Oeuq7Hi8nMIzx4/YlZuvWFiSOHZt27p4HmThCnNO/9IDFPmvPrpkYjWN5eN9Nuk+P5vZUb4A7QJgYpvGA==", "license": "Apache-2.0", "dependencies": { - "@react-types/shared": "^3.27.0" + "@react-types/shared": "^3.33.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/calendar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@react-types/calendar/-/calendar-3.6.0.tgz", - "integrity": "sha512-BtFh4BFwvsYlsaSqUOVxlqXZSlJ6u4aozgO3PwHykhpemwidlzNwm9qDZhcMWPioNF/w2cU/6EqhvEKUHDnFZg==", + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/@react-types/calendar/-/calendar-3.8.2.tgz", + "integrity": "sha512-QbPFhvBQfrsz3x1Nnatr5SL+8XtbxvP4obESFuDrKmsqaaAv+jG5vwLiPTKp6Z3L+MWkCvKavBPuW+byhq+69A==", "license": "Apache-2.0", "dependencies": { - "@internationalized/date": "^3.7.0", - "@react-types/shared": "^3.27.0" + "@internationalized/date": "^3.11.0", + "@react-types/shared": "^3.33.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/checkbox": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@react-types/checkbox/-/checkbox-3.9.1.tgz", - "integrity": "sha512-0x/KQcipfNM9Nvy6UMwYG25roRLvsiqf0J3woTYylNNWzF+72XT0iI5FdJkE3w2wfa0obmSoeq4WcbFREQrH/A==", + "version": "3.10.3", + "resolved": "https://registry.npmjs.org/@react-types/checkbox/-/checkbox-3.10.3.tgz", + "integrity": "sha512-Xw4jHG7uK352Wc18XXzdzmtr3Xjg8d2tPoBGNgsw39f92EY2UpoDAPHxYR0BaDe04lGfAn6YwVivI4OGVbjXIg==", "license": "Apache-2.0", "dependencies": { - "@react-types/shared": "^3.27.0" + "@react-types/shared": "^3.33.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/color": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@react-types/color/-/color-3.0.2.tgz", - "integrity": "sha512-4k9c0l5SACwTtkHV0dQ0GrF0Kktk/NChkxtyu58BamyUQOsCe8sqny+uul2nPrqQvuVof/dkRjKhv/DVyyx2mw==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@react-types/color/-/color-3.1.3.tgz", + "integrity": "sha512-XM0x8iZpAf036w9qceD2RFroehLxKRwkVer7EvdJNs8K8iUN8TuhCagzsomiSJtyYh5MFysEVQ2ir85toiAFyw==", "license": "Apache-2.0", "dependencies": { - "@react-types/shared": "^3.27.0", - "@react-types/slider": "^3.7.8" + "@react-types/shared": "^3.33.0", + "@react-types/slider": "^3.8.3" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/combobox": { - "version": "3.13.2", - "resolved": "https://registry.npmjs.org/@react-types/combobox/-/combobox-3.13.2.tgz", - "integrity": "sha512-yl2yMcM5/v3lJiNZWjpAhQ9vRW6dD55CD4rYmO2K7XvzYJaFVT4WYI/AymPYD8RqomMp7coBmBHfHW0oupk8gg==", + "version": "3.13.11", + "resolved": "https://registry.npmjs.org/@react-types/combobox/-/combobox-3.13.11.tgz", + "integrity": "sha512-5/tdmTAvqPpiWzEeaV7uLLSbSTkkoQ1mVz6NfKMPuw4ZBkY3lPc9JDkkQjY/JrquZao+KY4Dx8ZIoS0NqkrFrw==", "license": "Apache-2.0", "dependencies": { - "@react-types/shared": "^3.27.0" + "@react-types/shared": "^3.33.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/datepicker": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/@react-types/datepicker/-/datepicker-3.10.0.tgz", - "integrity": "sha512-Att7y4NedNH1CogMDIX9URXgMLxGbZgnFCZ8oxgFAVndWzbh3TBcc4s7uoJDPvgRMAalq+z+SrlFFeoBeJmvvg==", + "version": "3.13.4", + "resolved": "https://registry.npmjs.org/@react-types/datepicker/-/datepicker-3.13.4.tgz", + "integrity": "sha512-B5sAPoYZfluDBpgVK3ADlHbXBKRkFCQFO18Bs091IvRRwqzfoO/uf+/9UpXMw+BEF4pciLf0/kdiVQTvI3MzlA==", "license": "Apache-2.0", "dependencies": { - "@internationalized/date": "^3.7.0", - "@react-types/calendar": "^3.6.0", - "@react-types/overlays": "^3.8.12", - "@react-types/shared": "^3.27.0" + "@internationalized/date": "^3.11.0", + "@react-types/calendar": "^3.8.2", + "@react-types/overlays": "^3.9.3", + "@react-types/shared": "^3.33.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/dialog": { - "version": "3.5.15", - "resolved": "https://registry.npmjs.org/@react-types/dialog/-/dialog-3.5.15.tgz", - "integrity": "sha512-BX1+mV35Oa0aIlhu98OzJaSB7uiCWDPQbr0AkpFBajSSlESUoAjntN+4N+QJmj24z2v6UE9zxGQ85/U/0Le+bw==", + "version": "3.5.23", + "resolved": "https://registry.npmjs.org/@react-types/dialog/-/dialog-3.5.23.tgz", + "integrity": "sha512-3tMzweYuaDOaufF5tZPMgXSA0pPFJNgdg89YRITh0wMXMG0pm+tAKVQJL1TSLLhOiLCEL08V8M/AK67dBdr2IA==", "license": "Apache-2.0", "dependencies": { - "@react-types/overlays": "^3.8.12", - "@react-types/shared": "^3.27.0" + "@react-types/overlays": "^3.9.3", + "@react-types/shared": "^3.33.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/grid": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/@react-types/grid/-/grid-3.2.11.tgz", - "integrity": "sha512-Mww9nrasppvPbsBi+uUqFnf7ya8fXN0cTVzDNG+SveD8mhW+sbtuy+gPtEpnFD2Oyi8qLuObefzt4gdekJX2Yw==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/@react-types/grid/-/grid-3.3.7.tgz", + "integrity": "sha512-riET3xeKPTcRWQy6hYCMxdbdL3yubPY5Ow66b2GA2rEqoYvmDBniYXAM2Oh+q9s+YgnAP7qJK++ym8NljvHiLA==", "license": "Apache-2.0", "dependencies": { - "@react-types/shared": "^3.27.0" + "@react-types/shared": "^3.33.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/link": { - "version": "3.5.10", - "resolved": "https://registry.npmjs.org/@react-types/link/-/link-3.5.10.tgz", - "integrity": "sha512-IM2mbSpB0qP44Jh1Iqpevo7bQdZAr0iDyDi13OhsiUYJeWgPMHzGEnQqdBMkrfQeOTXLtZtUyOYLXE2v39bhzQ==", + "version": "3.6.6", + "resolved": "https://registry.npmjs.org/@react-types/link/-/link-3.6.6.tgz", + "integrity": "sha512-M6WXxUJFmiF6GNu7xUH0uHj0jsorFBN6npkfSCNM4puStC8NbUT2+ZPySQyZXCoHMQ89g6qZ6vCc8QduVkTE7Q==", "license": "Apache-2.0", "dependencies": { - "@react-types/shared": "^3.27.0" + "@react-types/shared": "^3.33.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/listbox": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/@react-types/listbox/-/listbox-3.5.4.tgz", - "integrity": "sha512-5otTes0zOwRZwNtqysPD/aW4qFJSxd5znjwoWTLnzDXXOBHXPyR83IJf8ITgvIE5C0y+EFadsWR/BBO3k9Pj7g==", + "version": "3.7.5", + "resolved": "https://registry.npmjs.org/@react-types/listbox/-/listbox-3.7.5.tgz", + "integrity": "sha512-Cn+yNip+YZBaGzu+z5xPNgmfSupnLl+li7uG5hRc+EArkk8/G42myRXz6M8wPrLM1bFAq3r85tAbyoXVmKG5Jw==", "license": "Apache-2.0", "dependencies": { - "@react-types/shared": "^3.27.0" + "@react-types/shared": "^3.33.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/menu": { - "version": "3.9.14", - "resolved": "https://registry.npmjs.org/@react-types/menu/-/menu-3.9.14.tgz", - "integrity": "sha512-RJW/S8IPwbRuohJ/A9HJ7W8QaAY816tm7Nv6+H/TLXG76zu2AS5vEgq+0TcCAWvJJwUdLDpJWJMlo0iIoIBtcg==", + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@react-types/menu/-/menu-3.10.6.tgz", + "integrity": "sha512-OJTznQ4xE/VddBJU+HO4x5tceSOdyQhiHA1bREE1aHl+PcgHOUZLdMjXp1zFaGF16HhItHJaxpifJ4hzf4hWQA==", "license": "Apache-2.0", "dependencies": { - "@react-types/overlays": "^3.8.12", - "@react-types/shared": "^3.27.0" + "@react-types/overlays": "^3.9.3", + "@react-types/shared": "^3.33.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/meter": { - "version": "3.4.6", - "resolved": "https://registry.npmjs.org/@react-types/meter/-/meter-3.4.6.tgz", - "integrity": "sha512-YczAht1VXy3s4fR6Dq0ibGsjulGHzS/A/K4tOruSNTL6EkYH9ktHX62Xk/OhCiKHxV315EbZ136WJaCeO4BgHw==", + "version": "3.4.14", + "resolved": "https://registry.npmjs.org/@react-types/meter/-/meter-3.4.14.tgz", + "integrity": "sha512-rNw0Do2AM3zLGZ0pSWweViuddg1uW99PWzE6RQXE8nsTHTeiwDZt9SYGdObEnjd+nJ3YzemqekG0Kqt93iNBcA==", "license": "Apache-2.0", "dependencies": { - "@react-types/progress": "^3.5.9" + "@react-types/progress": "^3.5.17" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/numberfield": { - "version": "3.8.8", - "resolved": "https://registry.npmjs.org/@react-types/numberfield/-/numberfield-3.8.8.tgz", - "integrity": "sha512-825JPppxDaWh0Zxb0Q+wSslgRQYOtQPCAuhszPuWEy6d2F/M+hLR+qQqvQm9+LfMbdwiTg6QK5wxdWFCp2t7jw==", + "version": "3.8.17", + "resolved": "https://registry.npmjs.org/@react-types/numberfield/-/numberfield-3.8.17.tgz", + "integrity": "sha512-Q9n24OaSMXrebMowbtowmHLNclknN3XkcBIaYMwA2BIGIl+fZFnI8MERM0pG87W+wki6FepDExsDW9YxQF4pnw==", "license": "Apache-2.0", "dependencies": { - "@react-types/shared": "^3.27.0" + "@react-types/shared": "^3.33.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/overlays": { - "version": "3.8.12", - "resolved": "https://registry.npmjs.org/@react-types/overlays/-/overlays-3.8.12.tgz", - "integrity": "sha512-ZvR1t0YV7/6j+6OD8VozKYjvsXT92+C/2LOIKozy7YUNS5KI4MkXbRZzJvkuRECVZOmx8JXKTUzhghWJM/3QuQ==", + "version": "3.9.3", + "resolved": "https://registry.npmjs.org/@react-types/overlays/-/overlays-3.9.3.tgz", + "integrity": "sha512-LzetThNNk8T26pQRbs1I7+isuFhdFYREy7wJCsZmbB0FnZgCukGTfOtThZWv+ry11veyVJiX68jfl4SV6ACTWA==", "license": "Apache-2.0", "dependencies": { - "@react-types/shared": "^3.27.0" + "@react-types/shared": "^3.33.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/progress": { - "version": "3.5.9", - "resolved": "https://registry.npmjs.org/@react-types/progress/-/progress-3.5.9.tgz", - "integrity": "sha512-zFxOzx3G8XUmHgpm037Hcayls5bqzXVa182E3iM7YWTmrjxJPKZ58XL0WWBgpTd+mJD7fTpnFdAZqSmFbtDOdA==", + "version": "3.5.17", + "resolved": "https://registry.npmjs.org/@react-types/progress/-/progress-3.5.17.tgz", + "integrity": "sha512-JtiGlek6QS04bFrRj1WfChjPNr7+3/+pd6yZayXGUkQUPHt1Z/cFnv3QZ/tSQTdUt1XXmjnCak9ZH9JQBqe64Q==", "license": "Apache-2.0", "dependencies": { - "@react-types/shared": "^3.27.0" + "@react-types/shared": "^3.33.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/radio": { - "version": "3.8.6", - "resolved": "https://registry.npmjs.org/@react-types/radio/-/radio-3.8.6.tgz", - "integrity": "sha512-woTQYdRFjPzuml4qcIf+2zmycRuM5w3fDS5vk6CQmComVUjOFPtD28zX3Z9kc9lSNzaBQz9ONZfFqkZ1gqfICA==", + "version": "3.9.3", + "resolved": "https://registry.npmjs.org/@react-types/radio/-/radio-3.9.3.tgz", + "integrity": "sha512-w2BrMGIiZxYXPCnnB2NQyifwE/rRFMIW87MyawrKO9zPSbnDkqLIHAAtqmlNk2zkz1ZEWjk9opNsuztjP7D4sA==", "license": "Apache-2.0", "dependencies": { - "@react-types/shared": "^3.27.0" + "@react-types/shared": "^3.33.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/searchfield": { - "version": "3.5.11", - "resolved": "https://registry.npmjs.org/@react-types/searchfield/-/searchfield-3.5.11.tgz", - "integrity": "sha512-MX8d9pgvxZxmgDwI0tiDaf6ijOY8XcRj0HM8Ocfttlk7PEFJK44p51WsUC+fPX1GmZni2JpFkx/haPOSLUECdw==", + "version": "3.6.7", + "resolved": "https://registry.npmjs.org/@react-types/searchfield/-/searchfield-3.6.7.tgz", + "integrity": "sha512-POo3spZcYD14aqo0f4eNbymJ8w9EKrlu0pOOjYYWI2P0GUSRmib9cBA9xZFhvRGHuNlHo3ePjeFitYQI7L3g1g==", "license": "Apache-2.0", "dependencies": { - "@react-types/shared": "^3.27.0", - "@react-types/textfield": "^3.11.0" + "@react-types/shared": "^3.33.0", + "@react-types/textfield": "^3.12.7" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/select": { - "version": "3.9.9", - "resolved": "https://registry.npmjs.org/@react-types/select/-/select-3.9.9.tgz", - "integrity": "sha512-/hCd0o+ztn29FKCmVec+v7t4JpOzz56o+KrG7NDq2pcRWqUR9kNwCjrPhSbJIIEDm4ubtrfPu41ysIuDvRd2Bg==", + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/@react-types/select/-/select-3.12.1.tgz", + "integrity": "sha512-PtIUymvQNIIzgr+piJtK/8gbH7akWtbswIbfoADPSxtZEd1/vfUIO0s8c750s3XYNlmx/4DrhugQsLYwgC35yg==", "license": "Apache-2.0", "dependencies": { - "@react-types/shared": "^3.27.0" + "@react-types/shared": "^3.33.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/shared": { - "version": "3.27.0", - "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.27.0.tgz", - "integrity": "sha512-gvznmLhi6JPEf0bsq7SwRYTHAKKq/wcmKqFez9sRdbED+SPMUmK5omfZ6w3EwUFQHbYUa4zPBYedQ7Knv70RMw==", + "version": "3.33.0", + "resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.33.0.tgz", + "integrity": "sha512-xuUpP6MyuPmJtzNOqF5pzFUIHH2YogyOQfUQHag54PRmWB7AbjuGWBUv0l1UDmz6+AbzAYGmDVAzcRDOu2PFpw==", "license": "Apache-2.0", "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/slider": { - "version": "3.7.8", - "resolved": "https://registry.npmjs.org/@react-types/slider/-/slider-3.7.8.tgz", - "integrity": "sha512-utW1o9KT70hqFwu1zqMtyEWmP0kSATk4yx+Fm/peSR4iZa+BasRqH83yzir5GKc8OfqfE1kmEsSlO98/k986+w==", + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/@react-types/slider/-/slider-3.8.3.tgz", + "integrity": "sha512-HCDegYiUA27CcJKvFwgpR8ktFKf2nAirXqQEgVPV4uxk6JIeiRx41yqM/xPJGfmaqa7BARYARLT41yN2V8Kadg==", "license": "Apache-2.0", "dependencies": { - "@react-types/shared": "^3.27.0" + "@react-types/shared": "^3.33.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/switch": { - "version": "3.5.8", - "resolved": "https://registry.npmjs.org/@react-types/switch/-/switch-3.5.8.tgz", - "integrity": "sha512-sL7jmh8llF8BxzY4HXkSU4bwU8YU6gx45P85D0AdYXgRHxU9Cp7BQPOMF4pJoQ8TTej05MymY5q7xvJVmxUTAQ==", + "version": "3.5.16", + "resolved": "https://registry.npmjs.org/@react-types/switch/-/switch-3.5.16.tgz", + "integrity": "sha512-6fynclkyg0wGHo3f1bwk4Z+gZZEg0Z63iP5TFhgHWdZ8W+Uq6F3u7V4IgQpuJ2NleL1c2jy2/CKdS9v06ac2Og==", "license": "Apache-2.0", "dependencies": { - "@react-types/shared": "^3.27.0" + "@react-types/shared": "^3.33.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/table": { - "version": "3.10.4", - "resolved": "https://registry.npmjs.org/@react-types/table/-/table-3.10.4.tgz", - "integrity": "sha512-d0tLz/whxVteqr1rophtuuxqyknHHfTKeXrCgDjt8pAyd9U8GPDbfcFSfYPUhWdELRt7aLVyQw6VblZHioVEgQ==", + "version": "3.13.5", + "resolved": "https://registry.npmjs.org/@react-types/table/-/table-3.13.5.tgz", + "integrity": "sha512-4/CixlNmXSuJuX2IKuUlgNd/dEgNh3WvfE/bdwuI1t5JBdShP9tHIzSkgZbrzE2xX46NeA2xq4vXNO5kBv+QDA==", "license": "Apache-2.0", "dependencies": { - "@react-types/grid": "^3.2.11", - "@react-types/shared": "^3.27.0" + "@react-types/grid": "^3.3.7", + "@react-types/shared": "^3.33.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/tabs": { - "version": "3.3.12", - "resolved": "https://registry.npmjs.org/@react-types/tabs/-/tabs-3.3.12.tgz", - "integrity": "sha512-E9O9G+wf9kaQ8UbDEDliW/oxYlJnh7oDCW1zaMOySwnG4yeCh7Wu02EOCvlQW4xvgn/i+lbEWgirf7L+yj5nRg==", + "version": "3.3.21", + "resolved": "https://registry.npmjs.org/@react-types/tabs/-/tabs-3.3.21.tgz", + "integrity": "sha512-Dq9bKI62rHoI4LGGcBGlZ5s0aSwB0G4Y8o0r7hQZvf1eZWc9fmqdAdTTaGG/RUyhMIGRYWl5RRUBUuC5RmaO6w==", "license": "Apache-2.0", "dependencies": { - "@react-types/shared": "^3.27.0" + "@react-types/shared": "^3.33.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/textfield": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/@react-types/textfield/-/textfield-3.11.0.tgz", - "integrity": "sha512-YORBgr6wlu2xfvr4MqjKFHGpj+z8LBzk14FbWDbYnnhGnv0I10pj+m2KeOHgDNFHrfkDdDOQmMIKn1UCqeUuEg==", + "version": "3.12.7", + "resolved": "https://registry.npmjs.org/@react-types/textfield/-/textfield-3.12.7.tgz", + "integrity": "sha512-ddiacsS6sLFtAn2/fym7lR8nbdsLgPfelNDcsDqHiu6XUHh5TCNe8ItXHFaIiyfnKTH8uJqZrSli4wfAYNfMsw==", "license": "Apache-2.0", "dependencies": { - "@react-types/shared": "^3.27.0" + "@react-types/shared": "^3.33.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, "node_modules/@react-types/tooltip": { - "version": "3.4.14", - "resolved": "https://registry.npmjs.org/@react-types/tooltip/-/tooltip-3.4.14.tgz", - "integrity": "sha512-J7CeYL2yPeKIasx1rPaEefyCHGEx2DOCx+7bM3XcKGmCxvNdVQLjimNJOt8IHlUA0nFJQOjmSW/mz9P0f2/kUw==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@react-types/tooltip/-/tooltip-3.5.1.tgz", + "integrity": "sha512-h6xOAWbWUJKs9CzcCyzSPATLHq7W5dS866HkXLrtCrRDShLuzQnojZnctD2tKtNt17990hjnOhl36GUBuO5kyw==", "license": "Apache-2.0", "dependencies": { - "@react-types/overlays": "^3.8.12", - "@react-types/shared": "^3.27.0" + "@react-types/overlays": "^3.9.3", + "@react-types/shared": "^3.33.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1" } }, + "node_modules/@reduxjs/toolkit": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.11.2.tgz", + "integrity": "sha512-Kd6kAHTA6/nUpp8mySPqj3en3dm0tdMIgbttnQ1xFMVpufoj+ADi8pXLBsd4xzTRHQa7t/Jv8W5UnCuW4kuWMQ==", + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@standard-schema/utils": "^0.3.0", + "immer": "^11.0.0", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.1.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, + "node_modules/@reduxjs/toolkit/node_modules/immer": { + "version": "11.1.4", + "resolved": "https://registry.npmjs.org/immer/-/immer-11.1.4.tgz", + "integrity": "sha512-XREFCPo6ksxVzP4E0ekD5aMdf8WMwmdNaz6vuvxgI40UaEiu6q3p8X52aU6GdyvLY3XXX/8R7JOTXStz/nBbRw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz", + "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz", - "integrity": "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", + "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", "cpu": [ "arm" ], @@ -2631,9 +3086,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz", - "integrity": "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", + "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", "cpu": [ "arm64" ], @@ -2645,9 +3100,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz", - "integrity": "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", "cpu": [ "arm64" ], @@ -2659,9 +3114,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz", - "integrity": "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", + "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", "cpu": [ "x64" ], @@ -2673,9 +3128,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz", - "integrity": "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", + "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", "cpu": [ "arm64" ], @@ -2687,9 +3142,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz", - "integrity": "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", + "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", "cpu": [ "x64" ], @@ -2701,9 +3156,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz", - "integrity": "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", + "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", "cpu": [ "arm" ], @@ -2715,9 +3170,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz", - "integrity": "sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", + "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", "cpu": [ "arm" ], @@ -2729,9 +3184,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz", - "integrity": "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", + "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", "cpu": [ "arm64" ], @@ -2743,9 +3198,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz", - "integrity": "sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", + "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", "cpu": [ "arm64" ], @@ -2756,10 +3211,24 @@ "linux" ] }, - "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz", - "integrity": "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==", + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", + "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", + "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", "cpu": [ "loong64" ], @@ -2770,10 +3239,24 @@ "linux" ] }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz", - "integrity": "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==", + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", + "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", + "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", "cpu": [ "ppc64" ], @@ -2785,9 +3268,23 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz", - "integrity": "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", + "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", + "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", "cpu": [ "riscv64" ], @@ -2799,9 +3296,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz", - "integrity": "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", + "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", "cpu": [ "s390x" ], @@ -2813,9 +3310,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz", - "integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", + "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", "cpu": [ "x64" ], @@ -2827,9 +3324,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz", - "integrity": "sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", + "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", "cpu": [ "x64" ], @@ -2840,10 +3337,38 @@ "linux" ] }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", + "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", + "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz", - "integrity": "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", + "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", "cpu": [ "arm64" ], @@ -2855,9 +3380,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz", - "integrity": "sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", + "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", "cpu": [ "ia32" ], @@ -2868,10 +3393,24 @@ "win32" ] }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", + "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz", - "integrity": "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", + "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", "cpu": [ "x64" ], @@ -2882,22 +3421,34 @@ "win32" ] }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "license": "MIT" + }, + "node_modules/@standard-schema/utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", + "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", + "license": "MIT" + }, "node_modules/@swc/helpers": { - "version": "0.5.15", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", - "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.19.tgz", + "integrity": "sha512-QamiFeIK3txNjgUTNppE6MiG3p7TdninpZu0E0PbqVh1a9FNLT2FRhisaa4NcaX52XVhA5l7Pk58Ft7Sqi/2sA==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.8.0" } }, "node_modules/@tanstack/react-virtual": { - "version": "3.11.2", - "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.11.2.tgz", - "integrity": "sha512-OuFzMXPF4+xZgx8UzJha0AieuMihhhaWG0tCqpp6tDzlFwOmNBPYMuLOtMJ1Tr4pXLHmgjcWhG6RlknY2oNTdQ==", + "version": "3.13.18", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.13.18.tgz", + "integrity": "sha512-dZkhyfahpvlaV0rIKnvQiVoWPyURppl6w4m9IwMDpuIjcJ1sD9YGWrt0wISvgU7ewACXx2Ct46WPgI6qAD4v6A==", "license": "MIT", "dependencies": { - "@tanstack/virtual-core": "3.11.2" + "@tanstack/virtual-core": "3.13.18" }, "funding": { "type": "github", @@ -2909,9 +3460,9 @@ } }, "node_modules/@tanstack/virtual-core": { - "version": "3.11.2", - "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.11.2.tgz", - "integrity": "sha512-vTtpNt7mKCiZ1pwU9hfKPhpdVO2sVzFQsxoVBGtOSHxlrRRzYr8iQ2TlwbAcRYCcEiZ9ECAM8kBzH0v2+VzfKw==", + "version": "3.13.18", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.13.18.tgz", + "integrity": "sha512-Mx86Hqu1k39icq2Zusq+Ey2J6dDWTjDvEv43PJtRCoEYTLyfaPnxIQ6iy7YAOK0NV/qOEmZQ/uCufrppZxTgcg==", "license": "MIT", "funding": { "type": "github", @@ -2964,9 +3515,9 @@ } }, "node_modules/@types/d3-array": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", - "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz", + "integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==", "license": "MIT" }, "node_modules/@types/d3-color": { @@ -2991,9 +3542,9 @@ } }, "node_modules/@types/d3-path": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-1.0.11.tgz", - "integrity": "sha512-4pQMp8ldf7UaB/gR8Fvvy69psNHkTpD/pVw3vmEi8iZAB9EPMBruB1JvHO4BIq9QkUUd2lV1F5YXpMNj7JPBpw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", "license": "MIT" }, "node_modules/@types/d3-scale": { @@ -3006,13 +3557,12 @@ } }, "node_modules/@types/d3-shape": { - "version": "1.3.12", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-1.3.12.tgz", - "integrity": "sha512-8oMzcd4+poSLGgV0R1Q1rOlx/xdmozS4Xab7np0eamFFUYq71AU9pOCJEFnkXW2aI/oXdVYJzw6pssbSut7Z9Q==", - "dev": true, + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.8.tgz", + "integrity": "sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==", "license": "MIT", "dependencies": { - "@types/d3-path": "^1" + "@types/d3-path": "*" } }, "node_modules/@types/d3-time": { @@ -3028,16 +3578,9 @@ "license": "MIT" }, "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/history": { - "version": "4.7.11", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", - "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "dev": true, "license": "MIT" }, @@ -3053,105 +3596,78 @@ } }, "node_modules/@types/node": { - "version": "22.13.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.5.tgz", - "integrity": "sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg==", + "version": "25.3.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.3.tgz", + "integrity": "sha512-DpzbrH7wIcBaJibpKo9nnSQL0MTRdnWttGyE5haGwK86xgMOkFLp7vEyfQPGLOJh5wNYiJ3V9PmUMDhV9u8kkQ==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~6.20.0" + "undici-types": "~7.18.0" } }, "node_modules/@types/react": { - "version": "19.0.10", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.10.tgz", - "integrity": "sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==", - "dev": true, + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", + "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", + "devOptional": true, "license": "MIT", "dependencies": { - "csstype": "^3.0.2" + "csstype": "^3.2.2" } }, "node_modules/@types/react-dom": { - "version": "19.0.4", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.0.4.tgz", - "integrity": "sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg==", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", "dev": true, "license": "MIT", "peerDependencies": { - "@types/react": "^19.0.0" - } - }, - "node_modules/@types/react-router": { - "version": "5.1.20", - "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", - "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*" - } - }, - "node_modules/@types/react-router-dom": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", - "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router": "*" - } - }, - "node_modules/@types/recharts": { - "version": "1.8.29", - "resolved": "https://registry.npmjs.org/@types/recharts/-/recharts-1.8.29.tgz", - "integrity": "sha512-ulKklaVsnFIIhTQsQw226TnOibrddW1qUQNFVhoQEyY1Z7FRQrNecFCGt7msRuJseudzE9czVawZb17dK/aPXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/d3-shape": "^1", - "@types/react": "*" + "@types/react": "^19.2.0" } }, "node_modules/@types/styled-components": { - "version": "5.1.34", - "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.34.tgz", - "integrity": "sha512-mmiVvwpYklFIv9E8qfxuPyIt/OuyIrn6gMOAMOFUO3WJfSrSE+sGUoa4PiZj77Ut7bKZpaa6o1fBKS/4TOEvnA==", + "version": "5.1.36", + "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.36.tgz", + "integrity": "sha512-pGMRNY5G2rNDKEv2DOiFYa7Ft1r0jrhmgBwHhOMzPTgCjO76bCot0/4uEfqj7K0Jf1KdQmDtAuaDk9EAs9foSw==", "dev": true, "license": "MIT", "dependencies": { "@types/hoist-non-react-statics": "*", "@types/react": "*", - "csstype": "^3.0.2" + "csstype": "^3.2.2" } }, "node_modules/@types/stylis": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz", - "integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==", + "version": "4.2.7", + "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.7.tgz", + "integrity": "sha512-VgDNokpBoKF+wrdvhAAfS55OMQpL6QRglwTwNC3kIgBrzZxA4WsFj+2eLfEA/uMUDzBcEhYmjSbwQakn/i3ajA==", + "license": "MIT" + }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", + "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==", "license": "MIT" }, "node_modules/@vitejs/plugin-react": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz", - "integrity": "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.4.tgz", + "integrity": "sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.26.0", - "@babel/plugin-transform-react-jsx-self": "^7.25.9", - "@babel/plugin-transform-react-jsx-source": "^7.25.9", + "@babel/core": "^7.29.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-rc.3", "@types/babel__core": "^7.20.5", - "react-refresh": "^0.14.2" + "react-refresh": "^0.18.0" }, "engines": { - "node": "^14.18.0 || >=16.0.0" + "node": "^20.19.0 || >=22.12.0" }, "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "node_modules/asynckit": { @@ -3161,16 +3677,29 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.7.9", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", - "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz", + "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==", "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", "proxy-from-env": "^1.1.0" } }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz", + "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", @@ -3179,9 +3708,9 @@ "license": "ISC" }, "node_modules/browserslist": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", - "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "dev": true, "funding": [ { @@ -3199,10 +3728,11 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001688", - "electron-to-chromium": "^1.5.73", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.1" + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" @@ -3234,9 +3764,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001700", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001700.tgz", - "integrity": "sha512-2S6XIXwaE7K7erT8dY+kLQcpa5ms63XlRkMkReXjle+kf6c5g38vyMl+Z5y8dSxOFDhcFe+nxnn261PLxBSQsQ==", + "version": "1.0.30001775", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001775.tgz", + "integrity": "sha512-s3Qv7Lht9zbVKE9XoTyRG6wVDCKdtOFIjBGg3+Yhn6JaytuNKPIjBMTMIY1AnOH3seL5mvF+x33oGAyK3hVt3A==", "dev": true, "funding": [ { @@ -3255,26 +3785,26 @@ "license": "CC-BY-4.0" }, "node_modules/cheerio": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", - "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz", + "integrity": "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==", "dev": true, "license": "MIT", "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", "domhandler": "^5.0.3", - "domutils": "^3.1.0", - "encoding-sniffer": "^0.2.0", - "htmlparser2": "^9.1.0", - "parse5": "^7.1.2", - "parse5-htmlparser2-tree-adapter": "^7.0.0", + "domutils": "^3.2.2", + "encoding-sniffer": "^0.2.1", + "htmlparser2": "^10.1.0", + "parse5": "^7.3.0", + "parse5-htmlparser2-tree-adapter": "^7.1.0", "parse5-parser-stream": "^7.1.2", - "undici": "^6.19.5", + "undici": "^7.19.0", "whatwg-mimetype": "^4.0.0" }, "engines": { - "node": ">=18.17" + "node": ">=20.18.1" }, "funding": { "url": "https://github.com/cheeriojs/cheerio?sponsor=1" @@ -3333,11 +3863,11 @@ "license": "MIT" }, "node_modules/csp-toolkit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/csp-toolkit/-/csp-toolkit-1.3.0.tgz", - "integrity": "sha512-B/Wyne4cZAbYIYt64fv+lRXJ5rNUSSMHMB0By8GVtm2SEskOxoNwQRODsPzFsf9/sL6P59qLz7jvpmeuLz2+Nw==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/csp-toolkit/-/csp-toolkit-1.4.0.tgz", + "integrity": "sha512-ezMVB6+2RnsnN5ncHsLX8njyPMv7I0M6ZLDP4pgmRVS4JjCgiWyeY2vs0zVfFTbdCo0CQI47PFICiQOZ5tDiww==", "dev": true, - "license": "GPL-3.0-only" + "license": "MIT" }, "node_modules/css-color-keywords": { "version": "1.0.0", @@ -3349,9 +3879,9 @@ } }, "node_modules/css-select": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -3377,9 +3907,9 @@ } }, "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -3390,9 +3920,9 @@ } }, "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", "license": "MIT" }, "node_modules/d3-array": { @@ -3426,9 +3956,9 @@ } }, "node_modules/d3-format": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", - "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz", + "integrity": "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==", "license": "ISC", "engines": { "node": ">=12" @@ -3517,9 +4047,9 @@ } }, "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "license": "MIT", "dependencies": { @@ -3535,9 +4065,9 @@ } }, "node_modules/decimal.js": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz", - "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==", + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", "license": "MIT" }, "node_modules/decimal.js-light": { @@ -3555,16 +4085,6 @@ "node": ">=0.4.0" } }, - "node_modules/dom-helpers": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", - "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.8.7", - "csstype": "^3.0.2" - } - }, "node_modules/dom-serializer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", @@ -3625,27 +4145,21 @@ } }, "node_modules/downshift": { - "version": "9.0.8", - "resolved": "https://registry.npmjs.org/downshift/-/downshift-9.0.8.tgz", - "integrity": "sha512-59BWD7+hSUQIM1DeNPLirNNnZIO9qMdIK5GQ/Uo8q34gT4B78RBlb9dhzgnh0HfQTJj4T/JKYD8KoLAlMWnTsA==", + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/downshift/-/downshift-9.3.2.tgz", + "integrity": "sha512-5VD0WZLQDhipWiDU+K5ili3VDhGrXwlvOlSaSG1Cb0eS4XpssxVuoD09JNgju+bAzxB2Wvlwx+FwTE/FNdrqow==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.24.5", - "compute-scroll-into-view": "^3.1.0", + "@babel/runtime": "^7.28.6", + "compute-scroll-into-view": "^3.1.1", "prop-types": "^15.8.1", - "react-is": "18.2.0", - "tslib": "^2.6.2" + "react-is": "^18.2.0", + "tslib": "^2.8.1" }, "peerDependencies": { "react": ">=16.12.0" } }, - "node_modules/downshift/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "license": "MIT" - }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -3661,16 +4175,16 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.104", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.104.tgz", - "integrity": "sha512-Us9M2L4cO/zMBqVkJtnj353nQhMju9slHm62NprKTmdF3HH8wYOtNvDFq/JB2+ZRoGLzdvYDiATlMHs98XBM1g==", + "version": "1.5.302", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.302.tgz", + "integrity": "sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg==", "dev": true, "license": "ISC" }, "node_modules/encoding-sniffer": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz", - "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", + "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", "dev": true, "license": "MIT", "dependencies": { @@ -3739,10 +4253,20 @@ "node": ">= 0.4" } }, + "node_modules/es-toolkit": { + "version": "1.45.0", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.45.0.tgz", + "integrity": "sha512-RArCX+Zea16+R1jg4mH223Z8p/ivbJjIkU3oC6ld2bdUfmDxiCkFYSi9zLOR2anucWJUeH4Djnzgd0im0nD3dw==", + "license": "MIT", + "workspaces": [ + "docs", + "benchmarks" + ] + }, "node_modules/esbuild": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz", - "integrity": "sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", + "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -3753,31 +4277,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.0", - "@esbuild/android-arm": "0.25.0", - "@esbuild/android-arm64": "0.25.0", - "@esbuild/android-x64": "0.25.0", - "@esbuild/darwin-arm64": "0.25.0", - "@esbuild/darwin-x64": "0.25.0", - "@esbuild/freebsd-arm64": "0.25.0", - "@esbuild/freebsd-x64": "0.25.0", - "@esbuild/linux-arm": "0.25.0", - "@esbuild/linux-arm64": "0.25.0", - "@esbuild/linux-ia32": "0.25.0", - "@esbuild/linux-loong64": "0.25.0", - "@esbuild/linux-mips64el": "0.25.0", - "@esbuild/linux-ppc64": "0.25.0", - "@esbuild/linux-riscv64": "0.25.0", - "@esbuild/linux-s390x": "0.25.0", - "@esbuild/linux-x64": "0.25.0", - "@esbuild/netbsd-arm64": "0.25.0", - "@esbuild/netbsd-x64": "0.25.0", - "@esbuild/openbsd-arm64": "0.25.0", - "@esbuild/openbsd-x64": "0.25.0", - "@esbuild/sunos-x64": "0.25.0", - "@esbuild/win32-arm64": "0.25.0", - "@esbuild/win32-ia32": "0.25.0", - "@esbuild/win32-x64": "0.25.0" + "@esbuild/aix-ppc64": "0.27.3", + "@esbuild/android-arm": "0.27.3", + "@esbuild/android-arm64": "0.27.3", + "@esbuild/android-x64": "0.27.3", + "@esbuild/darwin-arm64": "0.27.3", + "@esbuild/darwin-x64": "0.27.3", + "@esbuild/freebsd-arm64": "0.27.3", + "@esbuild/freebsd-x64": "0.27.3", + "@esbuild/linux-arm": "0.27.3", + "@esbuild/linux-arm64": "0.27.3", + "@esbuild/linux-ia32": "0.27.3", + "@esbuild/linux-loong64": "0.27.3", + "@esbuild/linux-mips64el": "0.27.3", + "@esbuild/linux-ppc64": "0.27.3", + "@esbuild/linux-riscv64": "0.27.3", + "@esbuild/linux-s390x": "0.27.3", + "@esbuild/linux-x64": "0.27.3", + "@esbuild/netbsd-arm64": "0.27.3", + "@esbuild/netbsd-x64": "0.27.3", + "@esbuild/openbsd-arm64": "0.27.3", + "@esbuild/openbsd-x64": "0.27.3", + "@esbuild/openharmony-arm64": "0.27.3", + "@esbuild/sunos-x64": "0.27.3", + "@esbuild/win32-arm64": "0.27.3", + "@esbuild/win32-ia32": "0.27.3", + "@esbuild/win32-x64": "0.27.3" } }, "node_modules/escalade": { @@ -3791,24 +4316,33 @@ } }, "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", "license": "MIT" }, - "node_modules/fast-equals": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.2.2.tgz", - "integrity": "sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw==", + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, "license": "MIT", "engines": { - "node": ">=6.0.0" + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, "node_modules/follow-redirects": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", "funding": [ { "type": "individual", @@ -3826,14 +4360,15 @@ } }, "node_modules/form-data": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", - "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", "mime-types": "^2.1.12" }, "engines": { @@ -3912,9 +4447,9 @@ } }, "node_modules/globals": { - "version": "15.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", - "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "version": "17.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.4.0.tgz", + "integrity": "sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw==", "dev": true, "license": "MIT", "engines": { @@ -3975,6 +4510,16 @@ "node": ">= 0.4" } }, + "node_modules/history": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz", + "integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/runtime": "^7.7.6" + } + }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", @@ -3993,9 +4538,9 @@ "license": "MIT" }, "node_modules/htmlparser2": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", - "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", + "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", "dev": true, "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", @@ -4008,8 +4553,21 @@ "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", - "domutils": "^3.1.0", - "entities": "^4.5.0" + "domutils": "^3.2.2", + "entities": "^7.0.1" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/iconv-lite": { @@ -4025,6 +4583,16 @@ "node": ">=0.10.0" } }, + "node_modules/immer": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.2.0.tgz", + "integrity": "sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/internmap": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", @@ -4035,15 +4603,15 @@ } }, "node_modules/intl-messageformat": { - "version": "10.7.15", - "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.15.tgz", - "integrity": "sha512-LRyExsEsefQSBjU2p47oAheoKz+EOJxSLDdjOaEjdriajfHsMXOmV/EhMvYSg9bAgCUHasuAC+mcUBe/95PfIg==", + "version": "10.7.18", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.18.tgz", + "integrity": "sha512-m3Ofv/X/tV8Y3tHXLohcuVuhWKo7BBq62cqY15etqmLxg2DZ34AGGgQDeR+SCta2+zICb1NX83af0GJmbQ1++g==", "license": "BSD-3-Clause", "dependencies": { - "@formatjs/ecma402-abstract": "2.3.3", - "@formatjs/fast-memoize": "2.2.6", - "@formatjs/icu-messageformat-parser": "2.11.1", - "tslib": "2" + "@formatjs/ecma402-abstract": "2.3.6", + "@formatjs/fast-memoize": "2.2.7", + "@formatjs/icu-messageformat-parser": "2.11.4", + "tslib": "^2.8.0" } }, "node_modules/js-tokens": { @@ -4078,12 +4646,6 @@ "node": ">=6" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "license": "MIT" - }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -4144,9 +4706,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.8", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", - "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "funding": [ { "type": "github", @@ -4162,9 +4724,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", "dev": true, "license": "MIT" }, @@ -4191,13 +4753,13 @@ } }, "node_modules/parse5": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", - "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", "dev": true, "license": "MIT", "dependencies": { - "entities": "^4.5.0" + "entities": "^6.0.0" }, "funding": { "url": "https://github.com/inikulin/parse5?sponsor=1" @@ -4230,12 +4792,38 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "license": "ISC" }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/postcss": { "version": "8.4.49", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", @@ -4294,59 +4882,62 @@ "license": "MIT" }, "node_modules/react": { - "version": "19.0.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz", - "integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", + "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/react-aria": { - "version": "3.37.0", - "resolved": "https://registry.npmjs.org/react-aria/-/react-aria-3.37.0.tgz", - "integrity": "sha512-u3WUEMTcbQFaoHauHO3KhPaBYzEv1o42EdPcLAs05GBw9Q6Axlqwo73UFgMrsc2ElwLAZ4EKpSdWHLo1R5gfiw==", + "version": "3.46.0", + "resolved": "https://registry.npmjs.org/react-aria/-/react-aria-3.46.0.tgz", + "integrity": "sha512-We0diSsMK35jw53JFjgF9w8obBjehAUI/TRiynnzSrjRd9eoHYQcecHlptke/HEFxvya/Gcm+LA21Im1+qnIeQ==", "license": "Apache-2.0", "dependencies": { - "@internationalized/string": "^3.2.5", - "@react-aria/breadcrumbs": "^3.5.20", - "@react-aria/button": "^3.11.1", - "@react-aria/calendar": "^3.7.0", - "@react-aria/checkbox": "^3.15.1", - "@react-aria/color": "^3.0.3", - "@react-aria/combobox": "^3.11.1", - "@react-aria/datepicker": "^3.13.0", - "@react-aria/dialog": "^3.5.21", - "@react-aria/disclosure": "^3.0.1", - "@react-aria/dnd": "^3.8.1", - "@react-aria/focus": "^3.19.1", - "@react-aria/gridlist": "^3.10.1", - "@react-aria/i18n": "^3.12.5", - "@react-aria/interactions": "^3.23.0", - "@react-aria/label": "^3.7.14", - "@react-aria/link": "^3.7.8", - "@react-aria/listbox": "^3.14.0", - "@react-aria/menu": "^3.17.0", - "@react-aria/meter": "^3.4.19", - "@react-aria/numberfield": "^3.11.10", - "@react-aria/overlays": "^3.25.0", - "@react-aria/progress": "^3.4.19", - "@react-aria/radio": "^3.10.11", - "@react-aria/searchfield": "^3.8.0", - "@react-aria/select": "^3.15.1", - "@react-aria/selection": "^3.22.0", - "@react-aria/separator": "^3.4.5", - "@react-aria/slider": "^3.7.15", - "@react-aria/ssr": "^3.9.7", - "@react-aria/switch": "^3.6.11", - "@react-aria/table": "^3.16.1", - "@react-aria/tabs": "^3.9.9", - "@react-aria/tag": "^3.4.9", - "@react-aria/textfield": "^3.16.0", - "@react-aria/tooltip": "^3.7.11", - "@react-aria/utils": "^3.27.0", - "@react-aria/visually-hidden": "^3.8.19", - "@react-types/shared": "^3.27.0" + "@internationalized/string": "^3.2.7", + "@react-aria/breadcrumbs": "^3.5.31", + "@react-aria/button": "^3.14.4", + "@react-aria/calendar": "^3.9.4", + "@react-aria/checkbox": "^3.16.4", + "@react-aria/color": "^3.1.4", + "@react-aria/combobox": "^3.14.2", + "@react-aria/datepicker": "^3.16.0", + "@react-aria/dialog": "^3.5.33", + "@react-aria/disclosure": "^3.1.2", + "@react-aria/dnd": "^3.11.5", + "@react-aria/focus": "^3.21.4", + "@react-aria/gridlist": "^3.14.3", + "@react-aria/i18n": "^3.12.15", + "@react-aria/interactions": "^3.27.0", + "@react-aria/label": "^3.7.24", + "@react-aria/landmark": "^3.0.9", + "@react-aria/link": "^3.8.8", + "@react-aria/listbox": "^3.15.2", + "@react-aria/menu": "^3.20.0", + "@react-aria/meter": "^3.4.29", + "@react-aria/numberfield": "^3.12.4", + "@react-aria/overlays": "^3.31.1", + "@react-aria/progress": "^3.4.29", + "@react-aria/radio": "^3.12.4", + "@react-aria/searchfield": "^3.8.11", + "@react-aria/select": "^3.17.2", + "@react-aria/selection": "^3.27.1", + "@react-aria/separator": "^3.4.15", + "@react-aria/slider": "^3.8.4", + "@react-aria/ssr": "^3.9.10", + "@react-aria/switch": "^3.7.10", + "@react-aria/table": "^3.17.10", + "@react-aria/tabs": "^3.11.0", + "@react-aria/tag": "^3.8.0", + "@react-aria/textfield": "^3.18.4", + "@react-aria/toast": "^3.0.10", + "@react-aria/tooltip": "^3.9.1", + "@react-aria/tree": "^3.1.6", + "@react-aria/utils": "^3.33.0", + "@react-aria/visually-hidden": "^3.8.30", + "@react-types/shared": "^3.33.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1", @@ -4354,15 +4945,15 @@ } }, "node_modules/react-dom": { - "version": "19.0.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz", - "integrity": "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", + "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", "license": "MIT", "dependencies": { - "scheduler": "^0.25.0" + "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.0.0" + "react": "^19.2.4" } }, "node_modules/react-is": { @@ -4371,40 +4962,39 @@ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "license": "MIT" }, - "node_modules/react-oauth2-code-pkce": { - "version": "1.22.2", - "resolved": "https://registry.npmjs.org/react-oauth2-code-pkce/-/react-oauth2-code-pkce-1.22.2.tgz", - "integrity": "sha512-Mn6JfA6AhYkhCZ83CJDsTRhNFbXkZnTuhdaJgj2/W1bqkU29cQAZaVnWtQrlXOLKYq9Ete9SdBHSi93pPt6gVA==", + "node_modules/react-redux": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz", + "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==", "license": "MIT", + "dependencies": { + "@types/use-sync-external-store": "^0.0.6", + "use-sync-external-store": "^1.4.0" + }, "peerDependencies": { - "react": ">=16.8.0" + "@types/react": "^18.2.25 || ^19", + "react": "^18.0 || ^19", + "redux": "^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "redux": { + "optional": true + } } }, "node_modules/react-refresh": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", - "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", + "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/react-smooth": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.4.tgz", - "integrity": "sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q==", - "license": "MIT", - "dependencies": { - "fast-equals": "^5.0.1", - "prop-types": "^15.8.1", - "react-transition-group": "^4.4.5" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - } - }, "node_modules/react-toastify": { "version": "11.0.5", "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-11.0.5.tgz", @@ -4418,68 +5008,65 @@ "react-dom": "^18 || ^19" } }, - "node_modules/react-transition-group": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", - "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", - "license": "BSD-3-Clause", - "dependencies": { - "@babel/runtime": "^7.5.5", - "dom-helpers": "^5.0.1", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2" - }, - "peerDependencies": { - "react": ">=16.6.0", - "react-dom": ">=16.6.0" - } - }, "node_modules/recharts": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.15.1.tgz", - "integrity": "sha512-v8PUTUlyiDe56qUj82w/EDVuzEFXwEHp9/xOowGAZwfLjB9uAy3GllQVIYMWF6nU+qibx85WF75zD7AjqoT54Q==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-3.7.0.tgz", + "integrity": "sha512-l2VCsy3XXeraxIID9fx23eCb6iCBsxUQDnE8tWm6DFdszVAO7WVY/ChAD9wVit01y6B2PMupYiMmQwhgPHc9Ew==", "license": "MIT", + "workspaces": [ + "www" + ], "dependencies": { - "clsx": "^2.0.0", - "eventemitter3": "^4.0.1", - "lodash": "^4.17.21", - "react-is": "^18.3.1", - "react-smooth": "^4.0.4", - "recharts-scale": "^0.4.4", - "tiny-invariant": "^1.3.1", - "victory-vendor": "^36.6.8" + "@reduxjs/toolkit": "1.x.x || 2.x.x", + "clsx": "^2.1.1", + "decimal.js-light": "^2.5.1", + "es-toolkit": "^1.39.3", + "eventemitter3": "^5.0.1", + "immer": "^10.1.1", + "react-redux": "8.x.x || 9.x.x", + "reselect": "5.1.1", + "tiny-invariant": "^1.3.3", + "use-sync-external-store": "^1.2.2", + "victory-vendor": "^37.0.2" }, "engines": { - "node": ">=14" + "node": ">=18" }, "peerDependencies": { - "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-is": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, - "node_modules/recharts-scale": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", - "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", + "node_modules/redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", + "license": "MIT" + }, + "node_modules/redux-thunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", "license": "MIT", - "dependencies": { - "decimal.js-light": "^2.4.1" + "peerDependencies": { + "redux": "^5.0.0" } }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "node_modules/reselect": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", + "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", "license": "MIT" }, "node_modules/rollup": { - "version": "4.34.8", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.8.tgz", - "integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", + "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "1.0.6" + "@types/estree": "1.0.8" }, "bin": { "rollup": "dist/bin/rollup" @@ -4489,25 +5076,31 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.34.8", - "@rollup/rollup-android-arm64": "4.34.8", - "@rollup/rollup-darwin-arm64": "4.34.8", - "@rollup/rollup-darwin-x64": "4.34.8", - "@rollup/rollup-freebsd-arm64": "4.34.8", - "@rollup/rollup-freebsd-x64": "4.34.8", - "@rollup/rollup-linux-arm-gnueabihf": "4.34.8", - "@rollup/rollup-linux-arm-musleabihf": "4.34.8", - "@rollup/rollup-linux-arm64-gnu": "4.34.8", - "@rollup/rollup-linux-arm64-musl": "4.34.8", - "@rollup/rollup-linux-loongarch64-gnu": "4.34.8", - "@rollup/rollup-linux-powerpc64le-gnu": "4.34.8", - "@rollup/rollup-linux-riscv64-gnu": "4.34.8", - "@rollup/rollup-linux-s390x-gnu": "4.34.8", - "@rollup/rollup-linux-x64-gnu": "4.34.8", - "@rollup/rollup-linux-x64-musl": "4.34.8", - "@rollup/rollup-win32-arm64-msvc": "4.34.8", - "@rollup/rollup-win32-ia32-msvc": "4.34.8", - "@rollup/rollup-win32-x64-msvc": "4.34.8", + "@rollup/rollup-android-arm-eabi": "4.59.0", + "@rollup/rollup-android-arm64": "4.59.0", + "@rollup/rollup-darwin-arm64": "4.59.0", + "@rollup/rollup-darwin-x64": "4.59.0", + "@rollup/rollup-freebsd-arm64": "4.59.0", + "@rollup/rollup-freebsd-x64": "4.59.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", + "@rollup/rollup-linux-arm-musleabihf": "4.59.0", + "@rollup/rollup-linux-arm64-gnu": "4.59.0", + "@rollup/rollup-linux-arm64-musl": "4.59.0", + "@rollup/rollup-linux-loong64-gnu": "4.59.0", + "@rollup/rollup-linux-loong64-musl": "4.59.0", + "@rollup/rollup-linux-ppc64-gnu": "4.59.0", + "@rollup/rollup-linux-ppc64-musl": "4.59.0", + "@rollup/rollup-linux-riscv64-gnu": "4.59.0", + "@rollup/rollup-linux-riscv64-musl": "4.59.0", + "@rollup/rollup-linux-s390x-gnu": "4.59.0", + "@rollup/rollup-linux-x64-gnu": "4.59.0", + "@rollup/rollup-linux-x64-musl": "4.59.0", + "@rollup/rollup-openbsd-x64": "4.59.0", + "@rollup/rollup-openharmony-arm64": "4.59.0", + "@rollup/rollup-win32-arm64-msvc": "4.59.0", + "@rollup/rollup-win32-ia32-msvc": "4.59.0", + "@rollup/rollup-win32-x64-gnu": "4.59.0", + "@rollup/rollup-win32-x64-msvc": "4.59.0", "fsevents": "~2.3.2" } }, @@ -4519,9 +5112,9 @@ "license": "MIT" }, "node_modules/scheduler": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.25.0.tgz", - "integrity": "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", "license": "MIT" }, "node_modules/semver": { @@ -4550,20 +5143,20 @@ } }, "node_modules/styled-components": { - "version": "6.1.15", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.15.tgz", - "integrity": "sha512-PpOTEztW87Ua2xbmLa7yssjNyUF9vE7wdldRfn1I2E6RTkqknkBYpj771OxM/xrvRGinLy2oysa7GOd7NcZZIA==", + "version": "6.3.11", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.3.11.tgz", + "integrity": "sha512-opzgceGlQ5rdZdGwf9ddLW7EM2F4L7tgsgLn6fFzQ2JgE5EVQ4HZwNkcgB1p8WfOBx1GEZP3fa66ajJmtXhSrA==", "license": "MIT", "dependencies": { - "@emotion/is-prop-valid": "1.2.2", - "@emotion/unitless": "0.8.1", - "@types/stylis": "4.2.5", + "@emotion/is-prop-valid": "1.4.0", + "@emotion/unitless": "0.10.0", + "@types/stylis": "4.2.7", "css-to-react-native": "3.2.0", - "csstype": "3.1.3", + "csstype": "3.2.3", "postcss": "8.4.49", "shallowequal": "1.1.0", - "stylis": "4.3.2", - "tslib": "2.6.2" + "stylis": "4.3.6", + "tslib": "2.8.1" }, "engines": { "node": ">= 16" @@ -4575,24 +5168,23 @@ "peerDependencies": { "react": ">= 16.8.0", "react-dom": ">= 16.8.0" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } } }, - "node_modules/styled-components/node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", - "license": "0BSD" - }, "node_modules/stylis": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", - "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz", + "integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==", "license": "MIT" }, "node_modules/tabbable": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", - "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.4.0.tgz", + "integrity": "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==", "license": "MIT" }, "node_modules/tiny-invariant": { @@ -4601,6 +5193,23 @@ "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", "license": "MIT" }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -4608,9 +5217,9 @@ "license": "0BSD" }, "node_modules/typescript": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", - "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -4622,26 +5231,26 @@ } }, "node_modules/undici": { - "version": "6.21.1", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.1.tgz", - "integrity": "sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==", + "version": "7.22.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.22.0.tgz", + "integrity": "sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==", "dev": true, "license": "MIT", "engines": { - "node": ">=18.17" + "node": ">=20.18.1" } }, "node_modules/undici-types": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", - "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", "dev": true, "license": "MIT" }, "node_modules/update-browserslist-db": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", - "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, "funding": [ { @@ -4669,10 +5278,19 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/victory-vendor": { - "version": "36.9.2", - "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz", - "integrity": "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==", + "version": "37.3.6", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-37.3.6.tgz", + "integrity": "sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==", "license": "MIT AND ISC", "dependencies": { "@types/d3-array": "^3.0.3", @@ -4691,31 +5309,25 @@ "d3-timer": "^3.0.1" } }, - "node_modules/victory-vendor/node_modules/@types/d3-shape": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", - "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", - "license": "MIT", - "dependencies": { - "@types/d3-path": "*" - } - }, "node_modules/vite": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.0.tgz", - "integrity": "sha512-7dPxoo+WsT/64rDcwoOjk76XHj+TqNTIvHKcuMQ1k4/SeHDaQt5GFAeLYzrimZrMpn/O6DtdI03WUjdxuPM0oQ==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", + "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "^0.25.0", - "postcss": "^8.5.3", - "rollup": "^4.30.1" + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "node": "^20.19.0 || >=22.12.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -4724,14 +5336,14 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", - "less": "*", + "less": "^4.0.0", "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" @@ -4773,23 +5385,23 @@ } }, "node_modules/vite-plugin-csp-guard": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/vite-plugin-csp-guard/-/vite-plugin-csp-guard-2.0.2.tgz", - "integrity": "sha512-e0Bzm4HLmKP/71/tWfRgMsemsFpyhQzGZYWgXFIzCRNloCbSwc6OHZrwIHm8FnHfiPNAVR3DO/hjsMsrGQdHJg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/vite-plugin-csp-guard/-/vite-plugin-csp-guard-3.0.0.tgz", + "integrity": "sha512-1c4s/pzn6S22JOa75sFHIa9BwzwpUMwQO2cP1BOU4N+6d33E1EQ067mbPV5pa8UGut9hrfUZZsj4FTN2e8ZGbQ==", "dev": true, - "license": "GPL-3.0-only", + "license": "MIT", "dependencies": { - "cheerio": "^1.0.0", - "csp-toolkit": "1.3.0" + "cheerio": "^1.1.2", + "csp-toolkit": "1.4.0" }, "peerDependencies": { - "vite": ">=5.0.0" + "vite": "^7.0.0" } }, "node_modules/vite/node_modules/postcss": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", - "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "dev": true, "funding": [ { @@ -4807,7 +5419,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.8", + "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -4819,6 +5431,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", "dev": true, "license": "MIT", "dependencies": { diff --git a/web/package.json b/web/package.json index 0bfe9d0e..8c9a0531 100644 --- a/web/package.json +++ b/web/package.json @@ -4,29 +4,29 @@ "private": true, "type": "module", "dependencies": { - "@equinor/eds-core-react": "^0.43.0", - "@equinor/eds-icons": "^0.22.0", - "@equinor/eds-tokens": "^0.9.2", - "axios": "^1.7.9", - "react": "^19.0.0", - "react-dom": "^19.0.0", - "react-oauth2-code-pkce": "^1.22.2", + "@equinor/eds-core-react": "^2.3.7", + "@equinor/eds-icons": "^1.3.0", + "@equinor/eds-tokens": "^2.2.0", + "@microsoft/applicationinsights-react-js": "^19.3.8", + "@microsoft/applicationinsights-web": "^3.3.11", + "axios": "^1.13.6", + "react": "^19.2.4", + "react-dom": "^19.2.4", "react-toastify": "^11.0.5", - "recharts": "^2.15.1", - "styled-components": "^6.1.15" + "recharts": "^3.7.0", + "styled-components": "^6.3.11" }, "devDependencies": { - "@types/node": "^22.13.5", - "@types/react": "^19.0.10", - "@types/react-dom": "^19.0.4", - "@types/react-router-dom": "^5.3.3", - "@types/recharts": "^1.8.29", - "@types/styled-components": "^5.1.34", - "@vitejs/plugin-react": "^4.3.4", - "globals": "^15.15.0", - "typescript": "~5.7.2", - "vite": "^6.2.0", - "vite-plugin-csp-guard": "^2.0.2" + "@biomejs/biome": "2.4.4", + "@types/node": "^25.3.3", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@types/styled-components": "^5.1.36", + "@vitejs/plugin-react": "^5.1.4", + "globals": "^17.4.0", + "typescript": "~5.9.3", + "vite": "^7.3.1", + "vite-plugin-csp-guard": "^3.0.0" }, "scripts": { "start": "vite", diff --git a/web/src/Api.ts b/web/src/Api.ts deleted file mode 100644 index 82642713..00000000 --- a/web/src/Api.ts +++ /dev/null @@ -1,67 +0,0 @@ -import axios from 'axios' -import type { BridgeApiRequest, OptimizationApiData, ProductValues, ReportApiRequest } from './Types' - -const BASE_PATH = '/api' - -class OptimizerApi { - async postOptimizerApi(token: string, data: OptimizationApiData) { - return axios.post(`${BASE_PATH}/optimizer`, data, { - headers: { Authorization: `Bearer ${token}` }, - }) - } -} - -class CombinationApi { - async postCombinationApi(token: string, data: ProductValues[]) { - return axios.post(`${BASE_PATH}/combination`, data, { - headers: { Authorization: `Bearer ${token}` }, - }) - } -} - -class ReportApi { - async postReportApi(token: string, data: ReportApiRequest) { - return axios.post(`${BASE_PATH}/report`, data, { - headers: { Authorization: `Bearer ${token}` }, - responseType: 'blob', - }) - } -} - -class BridgeApi { - async postBridgeApi(token: string, data: BridgeApiRequest) { - return axios.post(`${BASE_PATH}/bridge`, data, { - headers: { Authorization: `Bearer ${token}` }, - }) - } -} - -class SyncApi { - async postSyncApi(token: string) { - return axios.post(`${BASE_PATH}/sync`, {}, { headers: { Authorization: `Bearer ${token}` } }) - } -} - -class ProductsApi { - async getProductsApi(token: string) { - return axios.get(`${BASE_PATH}/products`, { - headers: { Authorization: `Bearer ${token}` }, - }) - } -} - -class FractionsApi { - async getFractionsApi(token: string) { - return axios.get(`${BASE_PATH}/fractions`, { - headers: { Authorization: `Bearer ${token}` }, - }) - } -} - -export const ProductsAPI = new ProductsApi() -export const FractionsAPI = new FractionsApi() -export const OptimizerAPI = new OptimizerApi() -export const BridgeAPI = new BridgeApi() -export const CombinationAPI = new CombinationApi() -export const ReportAPI = new ReportApi() -export const SyncAPI = new SyncApi() diff --git a/web/src/App.tsx b/web/src/App.tsx index 0974b7b4..946cb382 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -1,31 +1,21 @@ -import { useContext, useState } from 'react' - -import Main from './Pages/Main' +import { Home } from './Pages/Home' import 'react-toastify/dist/ReactToastify.css' -import { AuthContext, type IAuthContext } from 'react-oauth2-code-pkce' +import { AppInsightsContext } from '@microsoft/applicationinsights-react-js' import { ToastContainer } from 'react-toastify' -import { ParticleSizeContext } from './Context' - -function App() { - const [particleRange, setParticleRange] = useState>([1.01, 1000]) - const { tokenData }: IAuthContext = useContext(AuthContext) +import { reactPlugin } from './lib/applicationInsights' +import { ParticleSizeContextProvider } from './lib/contexts/particle-size' +import { UserContextProvider } from './lib/contexts/user' - if (!tokenData) return <> +export function App() { return ( - <> - -
- + + + + + + - + ) } - -export default App diff --git a/web/src/Components/Bridging/BridgeContainer.tsx b/web/src/Components/Bridging/BridgeContainer.tsx index 07b35dc1..23f35d9a 100644 --- a/web/src/Components/Bridging/BridgeContainer.tsx +++ b/web/src/Components/Bridging/BridgeContainer.tsx @@ -1,12 +1,12 @@ -import { useContext, useEffect, useState } from 'react' -import { AuthContext } from 'react-oauth2-code-pkce' -import { FractionsAPI } from '../../Api' -import { BridgingOption, CeramicDiscsValues } from '../../Enums' -import type { Bridge } from '../../Types' -import { findGraphData } from '../../Utils' +import { useEffect, useState } from 'react' +import { ceramicDiscSizes } from '../../lib/constants/ceramicDiscSizes' +import { BridgingOption } from '../../lib/enums/BridgingOption' +import { useApi } from '../../lib/hooks/useApi' +import type { Bridge, GraphData } from '../../lib/types' +import { findGraphData } from '../../lib/utils/findGraphData' import { ErrorToast } from '../Common/Toast' -import BridgeGraph from './Graphs/BridgeGraph' -import InputContainer from './InputContainer' +import { BridgeGraph } from './Graphs/BridgeGraph' +import { InputContainer } from './InputContainer' import { differentiateArrayObjects } from './utils' type BridgeContainerProps = { @@ -17,19 +17,19 @@ type BridgeContainerProps = { setValue: (value: number) => void } -export default ({ bridges, mode, setMode, bridgeValue, setValue }: BridgeContainerProps) => { +export function BridgeContainer({ bridges, mode, setMode, bridgeValue, setValue }: BridgeContainerProps) { const [sizeFractions, setSizeFractions] = useState([]) const [unit, setUnit] = useState('mD') - const [bridgeValueHelperText, setBridgeValueHelperText] = useState(undefined) - const [bridgeValueVariant, setBridgeValueVariant] = useState(undefined) - const [optimalBridgeGraphData, setOptimalBridgeGraphData] = useState([]) - const [volumeData, setVolumeData] = useState([]) - const [cumulativeVolumeData, setCumulativeVolumeData] = useState([]) - const { token } = useContext(AuthContext) + const [bridgeValueHelperText, setBridgeValueHelperText] = useState() + const [bridgeValueVariant, setBridgeValueVariant] = useState<'error' | undefined>() + const [optimalBridgeGraphData, setOptimalBridgeGraphData] = useState([]) + const [volumeData, setVolumeData] = useState([]) + const [cumulativeVolumeData, setCumulativeVolumeData] = useState([]) + const { getFractions } = useApi() // Load size fractions once on first render useEffect(() => { - FractionsAPI.getFractionsApi(token) + getFractions() .then((response) => { setSizeFractions(response.data.size_fractions) }) @@ -45,7 +45,7 @@ export default ({ bridges, mode, setMode, bridgeValue, setValue }: BridgeContain } }, [bridges, sizeFractions]) - function onBridgeOptionChange(event) { + function onBridgeOptionChange(event: React.ChangeEvent) { switch (event.target.value) { case BridgingOption.PERMEABILITY: setMode(BridgingOption.PERMEABILITY) @@ -63,15 +63,15 @@ export default ({ bridges, mode, setMode, bridgeValue, setValue }: BridgeContain case BridgingOption.CERAMIC_DISCS: setMode(BridgingOption.CERAMIC_DISCS) setUnit('microns') - setValue(Number.parseInt(CeramicDiscsValues[0])) + setValue(Number(ceramicDiscSizes[0])) break default: return } } - function onBridgeValueChange(value) { - const newBridgeValue = Number.parseInt(value) + function onBridgeValueChange(value: string) { + const newBridgeValue = Number(value) // TODO: Setting invalid values on parent is not good setValue(newBridgeValue) diff --git a/web/src/Components/Bridging/Graphs/BridgeGraph.tsx b/web/src/Components/Bridging/Graphs/BridgeGraph.tsx index c5a48b08..2d7b18ec 100644 --- a/web/src/Components/Bridging/Graphs/BridgeGraph.tsx +++ b/web/src/Components/Bridging/Graphs/BridgeGraph.tsx @@ -1,19 +1,29 @@ import { Typography } from '@equinor/eds-core-react' -import { useContext, useEffect, useState } from 'react' -import { Area, AreaChart, CartesianGrid, Legend, ResponsiveContainer, Tooltip, XAxis, YAxis } from 'recharts' -import { ParticleSizeContext } from '../../../Context' -import type { Bridge, GraphData } from '../../../Types' +import { type ReactElement, useEffect, useState } from 'react' +import { + Area, + AreaChart, + CartesianGrid, + Legend, + ResponsiveContainer, + Tooltip, + type TooltipContentProps, + XAxis, + YAxis, +} from 'recharts' +import { useParticleSizeContext } from '../../../lib/contexts/particle-size' +import type { Bridge, GraphData } from '../../../lib/types' import { bridgeColor, graphColors } from '../styles' type BridgeGraphProps = { title: string graphData: GraphData[] sizeFractions: number[] - bridges: Bridge | undefined + bridges: Bridge showBridge?: boolean } -const CustomTooltip = ({ active, payload, label }) => { +function CustomTooltip({ active, payload, label }: TooltipContentProps): ReactElement | false { if (active && payload && payload.length) { return (
{ >
{`Particle size : ${label}µm`}
- {payload.map((graphData: GraphData) => ( + {payload.map((graphData) => (
{`${graphData.name}: ${graphData.value}%`}
))}
@@ -37,22 +47,22 @@ const CustomTooltip = ({ active, payload, label }) => { ) } - return null + return false } export function BridgeGraph({ title, graphData, sizeFractions, bridges, showBridge = true }: BridgeGraphProps) { const [particleFromPercentage, setParticleFromPercentage] = useState('0%') const [particleToPercentage, setParticleToPercentage] = useState('100%') - const particleRange = useContext(ParticleSizeContext) + const { from, to } = useParticleSizeContext() useEffect(() => { - setParticleFromPercentage(particleSizeOffsetPercentage(particleRange.from)) - if (particleRange.to > sizeFractions[sizeFractions.length - 1]) { + setParticleFromPercentage(particleSizeOffsetPercentage(from)) + if (to > sizeFractions[sizeFractions.length - 1]) { setParticleToPercentage(`${sizeFractions[sizeFractions.length - 1]}%`) } else { - setParticleToPercentage(particleSizeOffsetPercentage(particleRange.to)) + setParticleToPercentage(particleSizeOffsetPercentage(to)) } - }, [particleRange, sizeFractions]) + }, [from, to, sizeFractions]) function particleSizeOffsetPercentage(offsetSize: number) { const index = sizeFractions.findIndex((size) => size > offsetSize) @@ -104,7 +114,7 @@ export function BridgeGraph({ title, graphData, sizeFractions, bridges, showBrid }} height={70} /> - + {Object.entries(bridges).map(([name, _], index) => ( @@ -125,5 +135,3 @@ export function BridgeGraph({ title, graphData, sizeFractions, bridges, showBrid
) } - -export default BridgeGraph diff --git a/web/src/Components/Bridging/InputContainer.tsx b/web/src/Components/Bridging/InputContainer.tsx index dbb313c4..77ef1b6c 100644 --- a/web/src/Components/Bridging/InputContainer.tsx +++ b/web/src/Components/Bridging/InputContainer.tsx @@ -1,9 +1,9 @@ import { NativeSelect, Radio, TextField, Tooltip, Typography } from '@equinor/eds-core-react' -import type { Variants } from '@equinor/eds-core-react/dist/types/components/types' -import { BridgingOption, CeramicDiscsValues } from '../../Enums' -import type { GraphData } from '../../Types' -import { findDValue } from '../../Utils' -import { colors } from '../../colors' +import { ceramicDiscSizes } from '../../lib/constants/ceramicDiscSizes' +import { colors } from '../../lib/constants/colors' +import { BridgingOption } from '../../lib/enums/BridgingOption' +import type { GraphData } from '../../lib/types' +import { findDValue } from '../../lib/utils/findDValue' import { InputWrapper, RadioWrapper } from './styles' type InputContainerProps = { @@ -13,8 +13,8 @@ type InputContainerProps = { optimalBridgeGraphData: GraphData[] unit: string bridgeValue: number - bridgeValueVariant: Variants | undefined - bridgeValueHelperText: string + bridgeValueVariant: 'error' | undefined + bridgeValueHelperText: string | undefined } const InputLabels: { [key in BridgingOption]: string } = { @@ -24,7 +24,7 @@ const InputLabels: { [key in BridgingOption]: string } = { [BridgingOption.CERAMIC_DISCS]: 'Disk Size', } -const InputContainer = ({ +export function InputContainer({ mode, onBridgeOptionChange, onBridgeValueChange, @@ -33,7 +33,7 @@ const InputContainer = ({ bridgeValue, bridgeValueVariant, bridgeValueHelperText, -}: InputContainerProps) => { +}: InputContainerProps) { return (
- {CeramicDiscsValues.map((value, index) => { + {ceramicDiscSizes.map((value, index) => { return (
) } - -export default InputContainer diff --git a/web/src/Components/Bridging/styles.ts b/web/src/Components/Bridging/styles.ts index b00cbf2e..475f4c5e 100644 --- a/web/src/Components/Bridging/styles.ts +++ b/web/src/Components/Bridging/styles.ts @@ -11,16 +11,6 @@ export const RadioWrapper = styled.div` flex-direction: column; ` -export const StyledSelect = styled.select` - position: relative; - font-size: medium; - padding: 8px 16px; - border: 1px solid #dbdbdb; - cursor: pointer; - width: 150px; - background-color: #ffffff; -` - export const bridgeColor = '#000000' export const graphColors = [ diff --git a/web/src/Components/Bridging/utils.ts b/web/src/Components/Bridging/utils.ts index cd4bc639..28682d2a 100644 --- a/web/src/Components/Bridging/utils.ts +++ b/web/src/Components/Bridging/utils.ts @@ -1,4 +1,4 @@ -import type { GraphData } from '../../Types' +import type { GraphData } from '../../lib/types' export function differentiateArrayObjects(arr: GraphData[]): GraphData[] { return arr.map((currentObj, index, array) => { diff --git a/web/src/Components/Combinations/CardContainer.tsx b/web/src/Components/Combinations/CardContainer.tsx index cfdf5129..5f932056 100644 --- a/web/src/Components/Combinations/CardContainer.tsx +++ b/web/src/Components/Combinations/CardContainer.tsx @@ -1,13 +1,12 @@ import { Button, Icon } from '@equinor/eds-core-react' import { add } from '@equinor/eds-icons' -import { useContext, useEffect, useState } from 'react' -import { AuthContext, type IAuthContext } from 'react-oauth2-code-pkce' +import { useEffect, useState } from 'react' import styled from 'styled-components' -import { FractionsAPI } from '../../Api' -import type { Bridge, Combination, Combinations, Products } from '../../Types' +import { useApi } from '../../lib/hooks/useApi' +import type { Bridge, Combination, Combinations, Products } from '../../lib/types' import { ErrorToast } from '../Common/Toast' -import CombinationCard from './CombinationCard' +import { CombinationCard } from './CombinationCard' export const Card = styled.div` margin: 10px; padding: 10px; @@ -24,7 +23,7 @@ export const CombinationTableHeader = styled.div` display: flex; justify-content: space-between; align-items: self-end; - padding: 0px 10px; + padding: 0 10px; background-color: #f7f7f7; border-bottom: #bfbfbf 2px solid; ` @@ -36,7 +35,7 @@ export const CombinationTableValues = styled.div` padding-right: 10px; ` -interface CardContainerProps { +type CardContainerProps = { sacks: boolean products: Products combinations: Combinations @@ -48,7 +47,7 @@ interface CardContainerProps { bridges: Bridge } -const createCombinationName = (sacks: boolean, combinationMap: Combinations): string => { +function createCombinationName(sacks: boolean, combinationMap: Combinations): string { const combinationNames: Array = Object.keys(combinationMap).map((id) => combinationMap[id].name) let i = 1 @@ -63,7 +62,7 @@ const createCombinationName = (sacks: boolean, combinationMap: Combinations): st return 'Error name....' } -export const CardContainer = ({ +export function CardContainer({ sacks, products, combinations, @@ -73,13 +72,13 @@ export const CardContainer = ({ addCombination, removeBridge, bridges, -}: CardContainerProps) => { - const { token }: IAuthContext = useContext(AuthContext) +}: CardContainerProps) { + const { getFractions } = useApi() const [sizeFractions, setSizeFractions] = useState([]) // Load size fractions once on first render useEffect(() => { - FractionsAPI.getFractionsApi(token) + getFractions() .then((response) => { setSizeFractions(response.data.size_fractions) }) @@ -118,7 +117,7 @@ export const CardContainer = ({ name: createCombinationName(sacks, combinations), sacks: sacks, values: {}, - cumulative: null, + cumulative: [], }) }} > @@ -129,5 +128,3 @@ export const CardContainer = ({ ) } - -export default CardContainer diff --git a/web/src/Components/Combinations/CombinationCard.tsx b/web/src/Components/Combinations/CombinationCard.tsx index e1e743ff..5092ca89 100644 --- a/web/src/Components/Combinations/CombinationCard.tsx +++ b/web/src/Components/Combinations/CombinationCard.tsx @@ -1,15 +1,15 @@ import { Button, Icon, Input, Switch, Tooltip, Typography } from '@equinor/eds-core-react' import { delete_to_trash, edit } from '@equinor/eds-icons' -import { useContext, useEffect, useState } from 'react' -import { AuthContext, type IAuthContext } from 'react-oauth2-code-pkce' +import { useEffect, useState } from 'react' import styled from 'styled-components' -import { CombinationAPI } from '../../Api' -import type { Bridge, Combination, GraphData, Product, Products } from '../../Types' -import { findDValue, findGraphData } from '../../Utils' -import EditProducts from '../Common/EditProducts' +import { useApi } from '../../lib/hooks/useApi' +import type { Bridge, Combination, GraphData, Product, Products } from '../../lib/types' +import { findDValue } from '../../lib/utils/findDValue' +import { findGraphData } from '../../lib/utils/findGraphData' +import { EditProducts } from '../Common/EditProducts' import { ErrorToast } from '../Common/Toast' import { Card } from './CardContainer' -import CombinationTable from './CombinationTable' +import { CombinationTable } from './CombinationTable' const CardHeader = styled.div` display: flex; @@ -31,7 +31,7 @@ const DValues = styled.div` padding: 3px 5px 0 10px; ` -interface CombinationCardProps { +type CombinationCardProps = { sacks: boolean combination: Combination updateCombination: (c: Combination) => void @@ -43,7 +43,7 @@ interface CombinationCardProps { sizeFractions: number[] } -export const CombinationCard = ({ +export function CombinationCard({ sacks, allProducts, combination, @@ -53,17 +53,17 @@ export const CombinationCard = ({ removeBridge, enabledPlot, sizeFractions, -}: CombinationCardProps) => { +}: CombinationCardProps) { const [combinationName, setCombinationName] = useState(combination.name) const [totalMass, setTotalMass] = useState(0) const [totalDensity, setTotalDensity] = useState(0) const [enabledProducts, setEnabledProducts] = useState({}) - const { token }: IAuthContext = useContext(AuthContext) const [bridge, setBridge] = useState() const [D10, setD10] = useState(0) const [D50, setD50] = useState(0) const [D90, setD90] = useState(0) const [isHeaderEditable, setIsHeaderEditable] = useState(false) + const { calculateBridgeFromCombination: postCombination } = useApi() // On first render with products, set enabledProducts from saved combinations useEffect(() => { @@ -93,7 +93,7 @@ export const CombinationCard = ({ setTotalDensity(Math.round(newDensity * 10) / 10) } - CombinationAPI.postCombinationApi(token, Object.values(combination.values)) + postCombination(Object.values(combination.values)) .then((response) => { const newBridge: Bridge = { ...bridge, @@ -236,5 +236,3 @@ export const CombinationCard = ({ ) } - -export default CombinationCard diff --git a/web/src/Components/Combinations/CombinationTable.tsx b/web/src/Components/Combinations/CombinationTable.tsx index 6577715d..a95e9566 100644 --- a/web/src/Components/Combinations/CombinationTable.tsx +++ b/web/src/Components/Combinations/CombinationTable.tsx @@ -1,6 +1,6 @@ import { TextField } from '@equinor/eds-core-react' import { useEffect, useState } from 'react' -import type { Combination, Products, ProductsInCombination } from '../../Types' +import type { Combination, Products, ProductsInCombination } from '../../lib/types' import { CombinationTableHeader, CombinationTableValues } from './CardContainer' function setPercentages(newValues: ProductsInCombination, allProducts: Products): ProductsInCombination { @@ -20,7 +20,7 @@ function setPercentages(newValues: ProductsInCombination, allProducts: Products) return newValues } -interface CombinationTableProps { +type CombinationTableProps = { allProducts: Products sacks: boolean updateCombination: (c: Combination) => void @@ -28,13 +28,13 @@ interface CombinationTableProps { combinationName: string } -export const CombinationTable = ({ +export function CombinationTable({ allProducts, sacks, updateCombination, productsInCombination, combinationName, -}: CombinationTableProps) => { +}: CombinationTableProps) { const [values, setValues] = useState({}) const alternatingColor = ['white', '#F5F5F5'] @@ -42,14 +42,14 @@ export const CombinationTable = ({ setValues(setPercentages(productsInCombination, allProducts)) }, [productsInCombination, allProducts]) - const handleValueChange = (productId: string, newValue: string) => { + function handleValueChange(productId: string, newValue: string) { let value = newValue if (!value) { value = '0' } let formattedValue: number if (sacks) { - formattedValue = Number.parseInt(value) + formattedValue = Number(value) } else { formattedValue = Number.parseFloat(value) } @@ -65,7 +65,7 @@ export const CombinationTable = ({ name: combinationName, sacks: sacks, values: newValuesWithPercentage, - cumulative: null, + cumulative: [], }) } return ( @@ -117,5 +117,3 @@ export const CombinationTable = ({ ) } - -export default CombinationTable diff --git a/web/src/Components/Common/EditProducts.tsx b/web/src/Components/Common/EditProducts.tsx index ae8b7f91..6142a86a 100644 --- a/web/src/Components/Common/EditProducts.tsx +++ b/web/src/Components/Common/EditProducts.tsx @@ -1,15 +1,15 @@ import { Button, Dialog } from '@equinor/eds-core-react' import { type ReactElement, useEffect, useState } from 'react' -import type { Products } from '../../Types' -import SelectProducts from './SelectProducts' +import type { Products } from '../../lib/types' +import { SelectProducts } from './SelectProducts' -interface AddProductsProps { +type AddProductsProps = { allProducts: Products enabledProducts: Products setEnabledProducts: (products: Products) => void } -export const EditProducts = ({ allProducts, enabledProducts, setEnabledProducts }: AddProductsProps): ReactElement => { +export function EditProducts({ allProducts, enabledProducts, setEnabledProducts }: AddProductsProps): ReactElement { const [dialogOpen, setDialogOpen] = useState(false) const [selectedProducts, setSelectedProducts] = useState(enabledProducts) @@ -22,11 +22,16 @@ export const EditProducts = ({ allProducts, enabledProducts, setEnabledProducts - + Select products in blend - + ) } - -export default EditProducts diff --git a/web/src/Components/Common/SelectProducts.tsx b/web/src/Components/Common/SelectProducts.tsx index 45e53ca4..93b54050 100644 --- a/web/src/Components/Common/SelectProducts.tsx +++ b/web/src/Components/Common/SelectProducts.tsx @@ -1,10 +1,9 @@ import { Checkbox, Chip, Switch, Typography } from '@equinor/eds-core-react' -import type { ReactElement } from 'react' import styled from 'styled-components' -import useLocalStorage from '../../Hooks' -import type { Product, Products } from '../../Types' -import { sortProducts } from '../../Utils' +import { useLocalStorage } from '../../lib/hooks/useLocalStorage' +import type { Product, Products } from '../../lib/types' +import { sortProducts } from '../../lib/utils/sortProducts' const ChipBox = styled.div` display: flex; @@ -22,7 +21,7 @@ const ProductBox = styled.div` padding: 0 10px 0 0; ` -interface SelectProductsProps { +type SelectProductsProps = { allProducts: Products enabledProducts: Products setEnabledProducts: (p: Products) => void @@ -30,11 +29,7 @@ interface SelectProductsProps { type ChipBoxStates = 'default' | 'active' -export const SelectProducts = ({ - allProducts, - enabledProducts, - setEnabledProducts, -}: SelectProductsProps): ReactElement => { +export function SelectProducts({ allProducts, enabledProducts, setEnabledProducts }: SelectProductsProps) { const productList: Array = sortProducts(Object.values(allProducts)) // Create set to only keep unique suppliers, then back to array to map them. @@ -81,7 +76,7 @@ export const SelectProducts = ({ } return ( - <> +
@@ -164,8 +158,6 @@ export const SelectProducts = ({ ) })}
- +
) } - -export default SelectProducts diff --git a/web/src/Components/Common/Toast.tsx b/web/src/Components/Common/Toast.tsx index be3fc39a..43962d91 100644 --- a/web/src/Components/Common/Toast.tsx +++ b/web/src/Components/Common/Toast.tsx @@ -1,29 +1,8 @@ import { type Id, toast } from 'react-toastify' -export const ErrorToast = (msg: string, code?: number): Id => { - const title =

Error

+export function ErrorToast(msg: string, code?: number): Id { const config = { autoClose: 7000 } - if (code === 401) - return toast.error( - <> - {title} -

Session Expired

-

Please reload page

-
- {code} -
- , - config - ) - return toast.error( - <> - {title} -

{msg}

-
- {code} -
- , - config - ) + if (code === 401) return toast.error('Session Expired, please reload page', config) + return toast.error(msg, config) } diff --git a/web/src/Components/Common/Tooltip.tsx b/web/src/Components/Common/Tooltip.tsx index 33af333c..50948ca7 100644 --- a/web/src/Components/Common/Tooltip.tsx +++ b/web/src/Components/Common/Tooltip.tsx @@ -2,7 +2,7 @@ import { Tooltip as EDSTooltip, Icon } from '@equinor/eds-core-react' import { help_outline } from '@equinor/eds-icons' import type { ReactElement } from 'react' import styled from 'styled-components' -import { colors } from '../../colors' +import { colors } from '../../lib/constants/colors' const Wrapper = styled.div` justify-content: center; @@ -17,12 +17,12 @@ const TooltipWrapper = styled.div` align-items: center; ` -interface TooltipProps { +type TooltipProps = { text: string children: ReactElement } -export const Tooltip = ({ text, children }: TooltipProps): ReactElement => { +export function Tooltip({ text, children }: TooltipProps): ReactElement { return ( {children} diff --git a/web/src/Components/MainBody.tsx b/web/src/Components/MainBody.tsx index 9ea24111..e78ac5e6 100644 --- a/web/src/Components/MainBody.tsx +++ b/web/src/Components/MainBody.tsx @@ -1,37 +1,36 @@ import { Accordion, Button, Icon, Typography } from '@equinor/eds-core-react' import { delete_to_trash, visibility_off } from '@equinor/eds-icons' -import { type ReactElement, useContext, useEffect, useState } from 'react' -import { AuthContext, type IAuthContext } from 'react-oauth2-code-pkce' +import { useEffect, useState } from 'react' import styled from 'styled-components' -import { BridgeAPI, CombinationAPI } from '../Api' -import { BridgingOption } from '../Enums' -import useLocalStorage from '../Hooks' -import type { Bridge, Combination, Combinations, Products } from '../Types' -import { colors } from '../colors' -import BridgeContainer from './Bridging/BridgeContainer' -import CardContainer from './Combinations/CardContainer' +import { colors } from '../lib/constants/colors' +import { BridgingOption } from '../lib/enums/BridgingOption' +import { useApi } from '../lib/hooks/useApi' +import { useLocalStorage } from '../lib/hooks/useLocalStorage' +import type { Bridge, Combination, Combinations, Products } from '../lib/types' +import { BridgeContainer } from './Bridging/BridgeContainer' +import { CardContainer } from './Combinations/CardContainer' import { ErrorToast } from './Common/Toast' -import OptimizationContainer from './Optimization/OptimizationContainer' +import { OptimizationContainer } from './Optimization/OptimizationContainer' const MainComponentsWrapper = styled.div` padding: 16px 0 16px 0; ` -export interface MainBodyProps { +type MainBodyProps = { products: Products } -export default ({ products }: MainBodyProps): ReactElement => { +export function MainBody({ products }: MainBodyProps) { const [mode, setMode] = useState(BridgingOption.PERMEABILITY) const [bridgeValue, setBridgeValue] = useState(500) const [combinations, setCombinations] = useLocalStorage('combinations', {}) const [bridges, setBridges] = useState({ Bridge: [] }) - const { token }: IAuthContext = useContext(AuthContext) + const { calculateOptimalBridge: postBridge, calculateBridgeFromCombination: postCombination } = useApi() // Update optimal bridge useEffect(() => { if (!(bridgeValue >= 1)) return - BridgeAPI.postBridgeApi(token, { + postBridge({ option: mode, value: bridgeValue, }) @@ -42,12 +41,12 @@ export default ({ products }: MainBodyProps): ReactElement => { ErrorToast(`${error.response.data}`, error.response.status) console.error(`fetch error ${error}`) }) - }, [bridgeValue, mode, token]) + }, [bridgeValue, mode]) async function fetchBridges(_combinations: Combinations): Promise { return await Promise.all( Object.values(_combinations).map(async (c: Combination) => { - const res = await CombinationAPI.postCombinationApi(token, Object.values(c.values)) + const res = await postCombination(Object.values(c.values)) return { [c.name]: res.data.bridge } }) ) @@ -61,7 +60,7 @@ export default ({ products }: MainBodyProps): ReactElement => { newBridges = { ...newBridges, ...b } }) - BridgeAPI.postBridgeApi(token, { + postBridge({ option: mode, value: bridgeValue, }).then((response) => { @@ -73,7 +72,7 @@ export default ({ products }: MainBodyProps): ReactElement => { function updateCombinationAndFetchBridge(combination: Combination) { // Don't fetch with empty values if combination does not exist if (!Object.values(combination.values).length && !Object.keys(bridges).includes(combination.name)) return - CombinationAPI.postCombinationApi(token, Object.values(combination.values)) + postCombination(Object.values(combination.values)) .then((response) => { setBridges({ ...bridges, [combination.name]: response.data.bridge }) }) diff --git a/web/src/Components/Navbar/ContactButton.tsx b/web/src/Components/Navbar/ContactButton.tsx index 9be72be7..bbcf61ae 100644 --- a/web/src/Components/Navbar/ContactButton.tsx +++ b/web/src/Components/Navbar/ContactButton.tsx @@ -2,7 +2,7 @@ import { Button, Dialog, Icon } from '@equinor/eds-core-react' import { comment_important } from '@equinor/eds-icons' import { useState } from 'react' -export const ContactButton = () => { +export function ContactButton() { const [dialogOpen, setDialogOpen] = useState(false) return ( diff --git a/web/src/Components/Navbar/Navbar.tsx b/web/src/Components/Navbar/Navbar.tsx index 0c2943d7..69554a59 100644 --- a/web/src/Components/Navbar/Navbar.tsx +++ b/web/src/Components/Navbar/Navbar.tsx @@ -1,10 +1,10 @@ import { Button, Icon, TopBar, Typography } from '@equinor/eds-core-react' import { info_circle } from '@equinor/eds-icons' import { ContactButton } from './ContactButton' -import RefreshButton from './RefreshButton' +import { RefreshButton } from './RefreshButton' import { StyledLink } from './styles' -const Navbar = () => { +export function Navbar() { return ( @@ -39,5 +39,3 @@ const Navbar = () => { ) } - -export default Navbar diff --git a/web/src/Components/Navbar/RefreshButton.tsx b/web/src/Components/Navbar/RefreshButton.tsx index df4feb4f..b7bb7cd3 100644 --- a/web/src/Components/Navbar/RefreshButton.tsx +++ b/web/src/Components/Navbar/RefreshButton.tsx @@ -1,11 +1,8 @@ import { Button, CircularProgress, Dialog, Icon } from '@equinor/eds-core-react' -import { useContext, useState } from 'react' - import { refresh } from '@equinor/eds-icons' -import { AuthContext } from 'react-oauth2-code-pkce' -import type { IAuthContext } from 'react-oauth2-code-pkce' +import { useState } from 'react' import styled from 'styled-components' -import { SyncAPI } from '../../Api' +import { useApi } from '../../lib/hooks/useApi' import { ErrorToast } from '../Common/Toast' const ButtonWrapper = styled.div` @@ -14,13 +11,13 @@ const ButtonWrapper = styled.div` width: 100%; ` -export const RefreshButton = () => { +export function RefreshButton() { const [dialogOpen, setDialogOpen] = useState(false) const [loading, setLoading] = useState(false) - const { token }: IAuthContext = useContext(AuthContext) + const { synchronizeSharepoint: postSync } = useApi() - const syncSharePoint = () => { - SyncAPI.postSyncApi(token) + function syncSharePoint() { + postSync() .then(() => { setLoading(false) window.location.reload() @@ -82,5 +79,3 @@ export const RefreshButton = () => { ) } - -export default RefreshButton diff --git a/web/src/Components/Optimization/OptimizationContainer.tsx b/web/src/Components/Optimization/OptimizationContainer.tsx index b6279054..380419bf 100644 --- a/web/src/Components/Optimization/OptimizationContainer.tsx +++ b/web/src/Components/Optimization/OptimizationContainer.tsx @@ -1,55 +1,51 @@ -import { type ReactElement, useState } from 'react' -import type { Combination, OptimizationData, Products, ProductsInCombination } from '../../Types' -import OptimizationResult from './OptimizationResult' -import OptimizationRunner from './OptimizationRunner' +import { useState } from 'react' +import type { Combination, OptimizationData, Products, ProductsInCombination } from '../../lib/types' +import { OptimizationResult } from './OptimizationResult' +import { OptimizationRunner } from './OptimizationRunner' -interface OptimizationContainerProps { +type OptimizationContainerProps = { products: Products addCombinationsFromOptimization: (sackCombination: Combination, densityCombination: Combination) => void mode: string value: number } -export interface ProductResult { +export type ProductResult = { id: string value: number } -export const OptimizationContainer = ({ +export function OptimizationContainer({ products, mode, addCombinationsFromOptimization, value, -}: OptimizationContainerProps): ReactElement => { - const [densityOptimizationData, setDensityOptimizationData] = useState(undefined) +}: OptimizationContainerProps) { + const [densityOptimizationData, setDensityOptimizationData] = useState() - const convertDensityOptimizationToSacks = (densityOptimizationData: OptimizationData): ProductsInCombination => { - let sackProducts: ProductsInCombination = {} - Object.values(densityOptimizationData.products).map((product) => { + function convertDensityOptimizationToSacks(densityOptimizationData: OptimizationData): ProductsInCombination { + const sackProducts: ProductsInCombination = {} + for (const product of Object.values(densityOptimizationData.products)) { const SACK_KG: number = 25 const sackValue: number = Math.round((product.value * densityOptimizationData.chosenVolume) / SACK_KG) if (sackValue > 0) { - sackProducts = { - ...sackProducts, - [product.id]: { id: product.id, value: sackValue, percentage: 0 }, - } + sackProducts[product.id] = { id: product.id, value: sackValue, percentage: 0 } } - }) + } let totalNumberOfSacks = 0 - Object.values(sackProducts).map((product) => { + for (const product of Object.values(sackProducts)) { totalNumberOfSacks += product.value - }) - - Object.values(sackProducts).map((product) => { + } + for (const product of Object.values(sackProducts)) { sackProducts[product.id].percentage = (product.value / totalNumberOfSacks) * 100 - }) + } //NOTE: since densities can be rounded down to 0 sacks, number of products in optimization for density and sacks can differ return sackProducts } - const handleUpdate = (densityOptimizationData: OptimizationData) => { + function handleUpdate(densityOptimizationData: OptimizationData) { if (Object.keys(densityOptimizationData.products).length === 0) { alert('Could not find a solution. Try changing some parameters') return @@ -57,11 +53,7 @@ export const OptimizationContainer = ({ const sackOptimizationValues = convertDensityOptimizationToSacks(densityOptimizationData) setDensityOptimizationData(densityOptimizationData) - const datetime = new Date() - const timeString = `${datetime.getHours().toString().padStart(2, '0')}:${datetime - .getMinutes() - .toString() - .padStart(2, '0')}:${datetime.getSeconds().toString().padStart(2, '0')}` + const timeString = new Date().toLocaleTimeString('nb-NO') const sackResultName = `Optimized at ${timeString} (sacks)` const densityResultName = `Optimized at ${timeString} (theoretical)` @@ -69,14 +61,14 @@ export const OptimizationContainer = ({ name: sackResultName, sacks: true, values: sackOptimizationValues, - cumulative: null, + cumulative: [], } const densityCombination: Combination = { name: densityResultName, sacks: false, values: densityOptimizationData.products, - cumulative: null, + cumulative: [], } addCombinationsFromOptimization(sackCombination, densityCombination) @@ -89,5 +81,3 @@ export const OptimizationContainer = ({ ) } - -export default OptimizationContainer diff --git a/web/src/Components/Optimization/OptimizationResult.tsx b/web/src/Components/Optimization/OptimizationResult.tsx index fc47e271..b16bce6d 100644 --- a/web/src/Components/Optimization/OptimizationResult.tsx +++ b/web/src/Components/Optimization/OptimizationResult.tsx @@ -1,15 +1,15 @@ -import type { OptimizationData, Products } from '../../Types' -import SolutionData from '../Solution/SolutionData' -import SolutionVisualisations from '../Solution/SolutionVisualisations' +import type { OptimizationData, Products } from '../../lib/types' +import { SolutionData } from '../Solution/SolutionData' +import { SolutionVisualisations } from '../Solution/SolutionVisualisations' -interface OptimizationResultProps { +type OptimizationResultProps = { products: Products mode: string value: number - optimizationData: OptimizationData + optimizationData: OptimizationData | undefined } -export const OptimizationResult = ({ products, optimizationData }: OptimizationResultProps) => { +export function OptimizationResult({ products, optimizationData }: OptimizationResultProps) { if (!optimizationData) return null return ( @@ -21,5 +21,3 @@ export const OptimizationResult = ({ products, optimizationData }: OptimizationR ) } - -export default OptimizationResult diff --git a/web/src/Components/Optimization/OptimizationRunner.tsx b/web/src/Components/Optimization/OptimizationRunner.tsx index 65a0e9ae..9ec95bfd 100644 --- a/web/src/Components/Optimization/OptimizationRunner.tsx +++ b/web/src/Components/Optimization/OptimizationRunner.tsx @@ -1,23 +1,22 @@ import { Accordion, Button, CircularProgress, Dialog, Icon, TextField, Typography } from '@equinor/eds-core-react' import { info_circle, play } from '@equinor/eds-icons' -import { type ReactElement, useContext, useState } from 'react' -import { AuthContext } from 'react-oauth2-code-pkce' +import { type ReactElement, useState } from 'react' import styled from 'styled-components' -import { OptimizerAPI } from '../../Api' -import { ParticleSizeContext } from '../../Context' -import useLocalStorage from '../../Hooks' -import type { OptimizationData, Product, Products } from '../../Types' -import EditProducts from '../Common/EditProducts' +import { useParticleSizeContext } from '../../lib/contexts/particle-size' +import { useApi } from '../../lib/hooks/useApi' +import { useLocalStorage } from '../../lib/hooks/useLocalStorage' +import type { OptimizationData, Product, Products } from '../../lib/types' +import { EditProducts } from '../Common/EditProducts' import { ErrorToast } from '../Common/Toast' import { Tooltip } from '../Common/Tooltip' import BridgeFitnessFormulaImg from './FormulaPictures/BridgeFitnessFormula.png' import MassFitnessFormulaImg from './FormulaPictures/MassFitnessFormula.png' import numberOfProductsFitnessFormulaImg from './FormulaPictures/NumberOfProductsFitnessFormula.png' import totalFitnessFormulaImg from './FormulaPictures/TotalFitnessFormula.png' -import PillInput, { type Pill } from './PillInput' +import { type Pill, PillInput } from './PillInput' import { type Weight, WeightOptions } from './WeightOptions' -interface OptimizationContainerProps { +type OptimizationContainerProps = { allProducts: Products mode: string value: number @@ -40,12 +39,16 @@ const InputWrapper = styled.div` margin: 0 15px 0 0; ` -const OptimizationRunner = ({ mode, value, handleUpdate, allProducts }: OptimizationContainerProps): ReactElement => { +export function OptimizationRunner({ + mode, + value, + handleUpdate, + allProducts, +}: OptimizationContainerProps): ReactElement { const [dialogOpen, setDialogOpen] = useState(false) const [failedRun, setFailedRun] = useState(false) const [invalidInput, setInvalidInput] = useState(false) const [loading, setLoading] = useState(false) - const { token } = useContext(AuthContext) const [iterations, setIterations] = useState(2000) const [maxProducts, setMaxProducts] = useState(5) const [pill, setPill] = useState({ @@ -58,17 +61,17 @@ const OptimizationRunner = ({ mode, value, handleUpdate, allProducts }: Optimiza mass: 5, products: 5, }) - const particleRange = useContext(ParticleSizeContext) - + const { range, from, to, setFrom, setTo } = useParticleSizeContext() const [products, setProducts] = useLocalStorage('optimizerProducts', {}) + const { runOptimizer } = useApi() - const handleOptimize = () => { + function handleOptimize() { setLoading(true) - OptimizerAPI.postOptimizerApi(token, { + runOptimizer({ request: 'OPTIMAL_MIX', name: 'Optimal Blend', iterations: iterations, - particleRange: [particleRange.from, particleRange.to], + particleRange: range, maxProducts: maxProducts, value: value, option: mode, @@ -216,7 +219,7 @@ const OptimizationRunner = ({ mode, value, handleUpdate, allProducts }: Optimiza value={iterations.toString()} onChange={(event: React.ChangeEvent) => { if (event.target.value === '') setIterations(0) - const newValue = Number.parseInt(event.target.value) + const newValue = Number(event.target.value) if (Math.sign(newValue) >= 0) setIterations(newValue) }} disabled={loading} @@ -234,7 +237,7 @@ const OptimizationRunner = ({ mode, value, handleUpdate, allProducts }: Optimiza value={maxProducts.toString()} onChange={(event: React.ChangeEvent) => { if (event.target.value === '') setMaxProducts(0) - const newValue = Number.parseInt(event.target.value) + const newValue = Number(event.target.value) if (Math.sign(newValue) >= 0) setMaxProducts(newValue) }} disabled={loading} @@ -246,42 +249,38 @@ const OptimizationRunner = ({ mode, value, handleUpdate, allProducts }: Optimiza Particle sizes to consider - - {({ from, to, setRange }) => ( -
-
- ) => { - if (event.target.value === '') setRange([0, to]) - const newValue = Number.parseFloat(event.target.value) - if (Math.sign(newValue) >= 0) setRange([newValue, to]) - }} - disabled={loading} - /> -
-
- ) => { - if (event.target.value === '') setRange([from, 0]) - const newValue = Number.parseFloat(event.target.value) - if (Math.sign(newValue) >= 0) setRange([from, newValue]) - }} - disabled={loading} - /> -
-
- )} -
+
+
+ ) => { + if (event.target.value === '') setFrom(0) + const newValue = Number.parseFloat(event.target.value) + if (Math.sign(newValue) >= 0) setFrom(newValue) + }} + disabled={loading} + /> +
+
+ ) => { + if (event.target.value === '') setTo(0) + const newValue = Number.parseFloat(event.target.value) + if (Math.sign(newValue) >= 0) setTo(newValue) + }} + disabled={loading} + /> +
+
@@ -295,5 +294,3 @@ const OptimizationRunner = ({ mode, value, handleUpdate, allProducts }: Optimiza ) } - -export default OptimizationRunner diff --git a/web/src/Components/Optimization/PillInput.tsx b/web/src/Components/Optimization/PillInput.tsx index 81744260..74ce5ed0 100644 --- a/web/src/Components/Optimization/PillInput.tsx +++ b/web/src/Components/Optimization/PillInput.tsx @@ -6,20 +6,20 @@ enum PillInputType { DENSITY = 'density', } -export interface Pill { +export type Pill = { volume: number density: number mass: number } -interface PillInputProps { +type PillInputProps = { isLoading: boolean pill: Pill setPill: (pill: Pill) => void setInvalidInput: (value: boolean) => void } -const PillInput = ({ pill, setPill, isLoading, setInvalidInput }: PillInputProps): ReactElement => { +export function PillInput({ pill, setPill, isLoading, setInvalidInput }: PillInputProps): ReactElement { const [invalidVolume, setInvalidVolume] = useState(false) const [invalidDensity, setInvalidDensity] = useState(false) @@ -29,9 +29,9 @@ const PillInput = ({ pill, setPill, isLoading, setInvalidInput }: PillInputProps } else setInvalidInput(false) }, [invalidDensity, invalidVolume]) - const handleChange = (type: string, value: string) => { + function handleChange(type: string, value: string) { let newValue = 0 - if (value !== '') newValue = Number.parseInt(value) + if (value !== '') newValue = Number(value) if (Math.sign(newValue) <= 0) { type === PillInputType.VOLUME && setInvalidVolume(true) @@ -90,5 +90,3 @@ const PillInput = ({ pill, setPill, isLoading, setInvalidInput }: PillInputProps ) } - -export default PillInput diff --git a/web/src/Components/Optimization/WeightOptions.tsx b/web/src/Components/Optimization/WeightOptions.tsx index 9e138060..8c1922c1 100644 --- a/web/src/Components/Optimization/WeightOptions.tsx +++ b/web/src/Components/Optimization/WeightOptions.tsx @@ -11,31 +11,23 @@ const Wrapper = styled.div` border-radius: 10px; ` -export interface Weight { +export type Weight = { bridge: number mass: number products: number - environmental?: Array } -export enum Environmental { - GREEN = 'GREEN', - YELLOW = 'YELLOW', - RED = 'RED', - BLACK = 'BLACK', -} - -interface WeightOptionsProps { +type WeightOptionsProps = { weight: Weight setWeight: (weight: Weight) => void } -export const WeightOptions = ({ weight, setWeight }: WeightOptionsProps): ReactElement => { +export function WeightOptions({ weight, setWeight }: WeightOptionsProps): ReactElement { const { bridge, mass, products } = weight // after a recent update, the Slider component from equinor/eds is meant to be used for a range of numbers. // This function lets us use the Slider component for a single number instead - const getSliderValue = (value: number | number[]): number => { + function getSliderValue(value: number | number[]): number { if (typeof value === 'number') { return value } @@ -53,7 +45,7 @@ export const WeightOptions = ({ weight, setWeight }: WeightOptionsProps): ReactE 'Set importance (0-10) to fine tune the optimization algorithm. These values only has meaning relative to each other.' } > - Weigthing + Weighting
diff --git a/web/src/Components/Solution/PerformanceRadar.tsx b/web/src/Components/Solution/PerformanceRadar.tsx index bd07fd3b..aa6ec910 100644 --- a/web/src/Components/Solution/PerformanceRadar.tsx +++ b/web/src/Components/Solution/PerformanceRadar.tsx @@ -1,11 +1,11 @@ import { PolarAngleAxis, PolarGrid, PolarRadiusAxis, Radar, RadarChart } from 'recharts' -import type { OptimizationData } from '../../Types' +import type { OptimizationData } from '../../lib/types' -interface IPerformanceRadar { +type IPerformanceRadar = { optimizationData: OptimizationData } -export const PerformanceRadar = ({ optimizationData }: IPerformanceRadar) => { +export function PerformanceRadar({ optimizationData }: IPerformanceRadar) { const performanceData = optimizationData.performance const graphData = [ { @@ -33,5 +33,3 @@ export const PerformanceRadar = ({ optimizationData }: IPerformanceRadar) => { ) } - -export default PerformanceRadar diff --git a/web/src/Components/Solution/SolutionBarChart.tsx b/web/src/Components/Solution/SolutionBarChart.tsx index 08012028..0d27b547 100644 --- a/web/src/Components/Solution/SolutionBarChart.tsx +++ b/web/src/Components/Solution/SolutionBarChart.tsx @@ -1,10 +1,10 @@ import { PureComponent } from 'react' import { Bar, BarChart, CartesianGrid, Legend, Tooltip, XAxis, YAxis } from 'recharts' -import type { OptimizationData, Products } from '../../Types' +import type { OptimizationData, Products } from '../../lib/types' import type { ProductResult } from '../Optimization/OptimizationContainer' -interface CustomizedAxisTickProps { +type CustomizedAxisTickProps = { x: number y: number payload: { value: number } @@ -23,13 +23,13 @@ class CustomizedAxisTick extends PureComponent { } } -interface SolutionBarChartProps { +type SolutionBarChartProps = { products: Products optimizationData: OptimizationData } -export const SolutionBarChart = ({ optimizationData, products }: SolutionBarChartProps) => { - const graphData = () => { +export function SolutionBarChart({ optimizationData, products }: SolutionBarChartProps) { + function getGraphData() { return Object.values(optimizationData.products).map((productResult: ProductResult) => { return { name: products[productResult.id].title, @@ -39,7 +39,7 @@ export const SolutionBarChart = ({ optimizationData, products }: SolutionBarChar } return ( - + ) } -export default SolutionBarChart diff --git a/web/src/Components/Solution/SolutionData.tsx b/web/src/Components/Solution/SolutionData.tsx index fb5afc0d..064ad296 100644 --- a/web/src/Components/Solution/SolutionData.tsx +++ b/web/src/Components/Solution/SolutionData.tsx @@ -1,10 +1,10 @@ import { Button, CircularProgress, Icon, Typography } from '@equinor/eds-core-react' import { save } from '@equinor/eds-icons' -import { type ReactElement, useContext, useEffect, useState } from 'react' -import { AuthContext } from 'react-oauth2-code-pkce' +import { type ReactElement, useEffect, useState } from 'react' import styled from 'styled-components' -import { ReportAPI } from '../../Api' -import type { OptimizationData, Products } from '../../Types' +import { useUserContext } from '../../lib/contexts/user' +import { useApi } from '../../lib/hooks/useApi' +import type { OptimizationData, Products } from '../../lib/types' import { ErrorToast } from '../Common/Toast' import type { ProductResult } from '../Optimization/OptimizationContainer' @@ -22,18 +22,18 @@ const Spacer = styled.div` padding-bottom: 32px; ` -interface SolutionDataProps { +type SolutionDataProps = { optimizationData: OptimizationData products: Products } -interface DensitiesProps { +type DensitiesProps = { products: Products productResults: Array } -const Densities = ({ products, productResults }: DensitiesProps): ReactElement => { - const getSumOfDensities = () => { +function Densities({ products, productResults }: DensitiesProps): ReactElement { + function getSumOfDensities() { let sum = 0 Object.values(productResults).forEach((result) => { sum += result.value @@ -64,9 +64,10 @@ const Densities = ({ products, productResults }: DensitiesProps): ReactElement = ) } -const SolutionData = ({ products, optimizationData }: SolutionDataProps) => { - const { tokenData, token } = useContext(AuthContext) +export function SolutionData({ products, optimizationData }: SolutionDataProps) { const [loading, setLoading] = useState(false) + const { createReport: postReport } = useApi() + const { user } = useUserContext() useEffect(() => { window.scrollTo(0, 999999) @@ -84,11 +85,11 @@ const SolutionData = ({ products, optimizationData }: SolutionDataProps) => { totalMass: optimizationData.totalMass, products: optimizationData.products, weighting: optimizationData.weighting, - email: tokenData.upn || 'none', - user: tokenData.name, + email: user?.email ?? '', + user: user?.name ?? '', } setLoading(true) - ReportAPI.postReportApi(token, reportRequest) + postReport(reportRequest) .then((res) => { const link = document.createElement('a') link.href = window.URL.createObjectURL(res.data) @@ -134,5 +135,3 @@ const SolutionData = ({ products, optimizationData }: SolutionDataProps) => {
) } - -export default SolutionData diff --git a/web/src/Components/Solution/SolutionVisualisations.tsx b/web/src/Components/Solution/SolutionVisualisations.tsx index f55c234d..05323eaa 100644 --- a/web/src/Components/Solution/SolutionVisualisations.tsx +++ b/web/src/Components/Solution/SolutionVisualisations.tsx @@ -1,8 +1,8 @@ import { Typography } from '@equinor/eds-core-react' import styled from 'styled-components' -import type { OptimizationData, Products } from '../../Types' -import PerformanceRadar from './PerformanceRadar' -import SolutionBarChart from './SolutionBarChart' +import type { OptimizationData, Products } from '../../lib/types' +import { PerformanceRadar } from './PerformanceRadar' +import { SolutionBarChart } from './SolutionBarChart' const Grid = styled.div` height: auto; @@ -13,12 +13,12 @@ const Grid = styled.div` align-items: center; ` -interface SolutionVisualisationsProps { +type SolutionVisualisationsProps = { optimizationData: OptimizationData products: Products } -export const SolutionVisualisations = ({ optimizationData, products }: SolutionVisualisationsProps) => { +export function SolutionVisualisations({ optimizationData, products }: SolutionVisualisationsProps) { return (
) } - -export default SolutionVisualisations diff --git a/web/src/Context.ts b/web/src/Context.ts deleted file mode 100644 index 97b34938..00000000 --- a/web/src/Context.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { createContext } from 'react' - -interface ParticleRange { - from: number - to: number - setRange: (range: number[]) => void -} - -export const ParticleSizeContext = createContext({ - from: 1, - to: 1000, - setRange: () => {}, -}) - -export interface User { - token: string - email: string - name: string -} diff --git a/web/src/Pages/Main.tsx b/web/src/Pages/Home.tsx similarity index 55% rename from web/src/Pages/Main.tsx rename to web/src/Pages/Home.tsx index 04ff98f0..aecd6dd4 100644 --- a/web/src/Pages/Main.tsx +++ b/web/src/Pages/Home.tsx @@ -1,14 +1,11 @@ -import { type ReactElement, useContext, useEffect, useState } from 'react' -import { AuthContext } from 'react-oauth2-code-pkce' -import type { IAuthContext } from 'react-oauth2-code-pkce' - +import { useEffect, useState } from 'react' import styled from 'styled-components' - -import { ProductsAPI } from '../Api' import { ErrorToast } from '../Components/Common/Toast' -import Body from '../Components/MainBody' -import Navbar from '../Components/Navbar/Navbar' -import type { Products } from '../Types' +import { MainBody } from '../Components/MainBody' +import { Navbar } from '../Components/Navbar/Navbar' +import { useAppInsights } from '../lib/applicationInsights' +import { useApi } from '../lib/hooks/useApi' +import type { Products } from '../lib/types' const BodyWrapper = styled.div` display: flex; @@ -18,13 +15,14 @@ const BodyWrapper = styled.div` font-family: 'Equinor'; ` -export default (): ReactElement => { +export function Home() { const [products, setProducts] = useState({}) - const { token }: IAuthContext = useContext(AuthContext) + const { getProducts } = useApi() + useAppInsights() // On first render, fetch all products useEffect(() => { - ProductsAPI.getProductsApi(token) + getProducts() .then((response) => { setProducts(response.data) }) @@ -38,7 +36,7 @@ export default (): ReactElement => { <> - + ) diff --git a/web/src/lib/applicationInsights.ts b/web/src/lib/applicationInsights.ts new file mode 100644 index 00000000..80183b19 --- /dev/null +++ b/web/src/lib/applicationInsights.ts @@ -0,0 +1,32 @@ +import { ReactPlugin, useAppInsightsContext } from '@microsoft/applicationinsights-react-js' +import { ApplicationInsights } from '@microsoft/applicationinsights-web' +import { useRef } from 'react' + +const connectionString = import.meta.env.VITE_APPINSIGHTS_CON_STRING || '' + +export const reactPlugin = new ReactPlugin() +export const appInsights = new ApplicationInsights({ + config: { + connectionString: connectionString, + enableAutoRouteTracking: false, + maxBatchInterval: 0, + extensions: [reactPlugin], + }, +}) + +if (connectionString) { + appInsights.loadAppInsights() +} else { + console.error('Application Insights connection string is not defined') +} + +export function useAppInsights() { + const hasTrackedInitialPageView = useRef(false) + const reactAppInsights = useAppInsightsContext() + + if (!hasTrackedInitialPageView.current) { + reactAppInsights.trackPageView({ isLoggedIn: true }) + reactAppInsights.trackEvent({ name: 'Main page load', properties: {} }) + hasTrackedInitialPageView.current = true + } +} diff --git a/web/src/lib/constants/ceramicDiscSizes.ts b/web/src/lib/constants/ceramicDiscSizes.ts new file mode 100644 index 00000000..d99f6935 --- /dev/null +++ b/web/src/lib/constants/ceramicDiscSizes.ts @@ -0,0 +1 @@ +export const ceramicDiscSizes = ['10', '12', '20', '40', '50', '55', '120'] as const diff --git a/web/src/colors.ts b/web/src/lib/constants/colors.ts similarity index 100% rename from web/src/colors.ts rename to web/src/lib/constants/colors.ts diff --git a/web/src/lib/contexts/particle-size.tsx b/web/src/lib/contexts/particle-size.tsx new file mode 100644 index 00000000..1f0e1213 --- /dev/null +++ b/web/src/lib/contexts/particle-size.tsx @@ -0,0 +1,46 @@ +import { createContext, useContext, useState } from 'react' + +type ParticleSizeContextType = { + from: number + to: number + range: [number, number] + setFrom: (from: number) => void + setTo: (to: number) => void + setRange: (range: [number, number]) => void +} + +export const ParticleSizeContext = createContext(undefined) + +export function ParticleSizeContextProvider({ children }: { children: React.ReactNode }) { + const [from, setFrom] = useState(1.01) + const [to, setTo] = useState(1000) + + const range = [from, to] as [number, number] + function setRange(range: [number, number]) { + setFrom(range[0]) + setTo(range[1]) + } + + return ( + + {children} + + ) +} + +export function useParticleSizeContext(): ParticleSizeContextType { + const context = useContext(ParticleSizeContext) + if (!context) { + throw new Error('useParticleSizeContext must be used within a ParticleSizeContextProvider') + } + return context +} diff --git a/web/src/lib/contexts/user.tsx b/web/src/lib/contexts/user.tsx new file mode 100644 index 00000000..243a1abe --- /dev/null +++ b/web/src/lib/contexts/user.tsx @@ -0,0 +1,41 @@ +import axios from 'axios' +import { createContext, useContext, useEffect, useState } from 'react' + +type User = { + name: string + email: string + oid: string +} + +type UserContextType = { + user: User | undefined +} + +const UserContext = createContext(undefined) + +export function UserContextProvider({ children }: { children: React.ReactNode }) { + const [user, setUser] = useState(undefined) + + useEffect(() => { + axios + .get('/api/me') + .then((res) => setUser(res.data)) + .catch((error) => { + if (axios.isAxiosError(error) && error.response?.status === 401) { + window.location.href = '/oauth2/sign_in' + return + } + console.error('Failed to load current user:', error) + }) + }, []) + + return {children} +} + +export function useUserContext(): UserContextType { + const context = useContext(UserContext) + if (!context) { + throw new Error('useUserContext must be used within a UserContextProvider') + } + return context +} diff --git a/web/src/Enums.ts b/web/src/lib/enums/BridgingOption.ts similarity index 69% rename from web/src/Enums.ts rename to web/src/lib/enums/BridgingOption.ts index 9dd34e85..25d1ece7 100644 --- a/web/src/Enums.ts +++ b/web/src/lib/enums/BridgingOption.ts @@ -4,5 +4,3 @@ export enum BridgingOption { MAXIMUM_PORESIZE = 'MAXIMUM_PORESIZE', CERAMIC_DISCS = 'CERAMIC_DISCS', } - -export const CeramicDiscsValues = ['10', '12', '20', '40', '50', '55', '120'] diff --git a/web/src/lib/hooks/useApi.ts b/web/src/lib/hooks/useApi.ts new file mode 100644 index 00000000..c6d400f9 --- /dev/null +++ b/web/src/lib/hooks/useApi.ts @@ -0,0 +1,54 @@ +import axios from 'axios' +import type { BridgeApiRequest, OptimizationApiData, ProductValues, ReportApiRequest } from '../types' + +export function useApi() { + const BASE_PATH = '/api' + + function apiPost(endpoint: string, data: T, responseType: 'blob' | 'json' = 'json') { + return axios.post(`${BASE_PATH}/${endpoint}`, data, { + responseType, + }) + } + + function apiGet(endpoint: string) { + return axios.get(`${BASE_PATH}/${endpoint}`) + } + + function runOptimizer(data: OptimizationApiData) { + return apiPost('optimizer', data) + } + + function calculateBridgeFromCombination(data: ProductValues[]) { + return apiPost('combination', data) + } + + function createReport(data: ReportApiRequest) { + return apiPost('report', data, 'blob') + } + + function calculateOptimalBridge(data: BridgeApiRequest) { + return apiPost('bridge', data) + } + + function synchronizeSharepoint() { + return apiPost('sync', {}) + } + + function getProducts() { + return apiGet('products') + } + + function getFractions() { + return apiGet('fractions') + } + + return { + runOptimizer, + calculateBridgeFromCombination, + createReport, + calculateOptimalBridge, + synchronizeSharepoint, + getProducts, + getFractions, + } +} diff --git a/web/src/Hooks.tsx b/web/src/lib/hooks/useLocalStorage.ts similarity index 77% rename from web/src/Hooks.tsx rename to web/src/lib/hooks/useLocalStorage.ts index 4b8c1cc2..a3187795 100644 --- a/web/src/Hooks.tsx +++ b/web/src/lib/hooks/useLocalStorage.ts @@ -1,6 +1,6 @@ import { useState } from 'react' -function useLocalStorage(key: string, initialValue: T): [T, (value: T) => void] { +export function useLocalStorage(key: string, initialValue: T): [T, (value: T) => void] { const [storedValue, setStoredValue] = useState(() => { try { const item = window.localStorage.getItem(key) @@ -11,7 +11,7 @@ function useLocalStorage(key: string, initialValue: T): [T, (value: T) => voi } }) - const setValue = (value: T | ((val: T) => T)) => { + function setValue(value: T | ((val: T) => T)) { try { const valueToStore = value instanceof Function ? value(storedValue) : value setStoredValue(valueToStore) @@ -23,5 +23,3 @@ function useLocalStorage(key: string, initialValue: T): [T, (value: T) => voi return [storedValue, setValue] } - -export default useLocalStorage diff --git a/web/src/Types.ts b/web/src/lib/types.ts similarity index 74% rename from web/src/Types.ts rename to web/src/lib/types.ts index 92633dc5..b8680ca7 100644 --- a/web/src/Types.ts +++ b/web/src/lib/types.ts @@ -1,6 +1,6 @@ -import type { Weight } from './Components/Optimization/WeightOptions' +import type { Weight } from '../Components/Optimization/WeightOptions' -export interface Product { +export type Product = { id: string title: string supplier: string @@ -13,53 +13,53 @@ export interface Product { cumulative: Array | null } -export interface Products { +export type Products = { [id: string]: Product } -export interface ProductValues { +export type ProductValues = { id: string value: number percentage: number } -export interface ProductsInCombination { +export type ProductsInCombination = { [id: string]: ProductValues } -export interface Combination { +export type Combination = { name: string sacks: boolean values: ProductsInCombination cumulative: Array } -export interface Combinations { +export type Combinations = { [name: string]: Combination } -export interface Bridge { +export type Bridge = { [name: string]: Array } -export interface GraphData { +export type GraphData = { size: number [name: string]: number } -export interface Performance { +export type Performance = { bridge: number mass: number products: number } -export interface Config { +export type Config = { iterations: number mode: string value: number } -export interface OptimizationData { +export type OptimizationData = { bridgeScore: number chosenMass: number chosenVolume: number @@ -77,7 +77,7 @@ export interface OptimizationData { weighting: Weight } -export interface OptimizationApiData { +export type OptimizationApiData = { request: string name: string iterations: number @@ -91,7 +91,7 @@ export interface OptimizationApiData { weights: Weight } -export interface ReportApiRequest { +export type ReportApiRequest = { fitness: number curve: Array pillVolume: number @@ -106,7 +106,7 @@ export interface ReportApiRequest { user: string } -export interface BridgeApiRequest { +export type BridgeApiRequest = { option: string value: number } diff --git a/web/src/Utils.ts b/web/src/lib/utils/findDValue.ts similarity index 62% rename from web/src/Utils.ts rename to web/src/lib/utils/findDValue.ts index 390f4640..a5cd04da 100644 --- a/web/src/Utils.ts +++ b/web/src/lib/utils/findDValue.ts @@ -1,31 +1,4 @@ -import type { Bridge, GraphData, Product } from './Types' - -export function sortProducts(products: Array): Array { - return products.sort((a, b) => { - if (a.supplier > b.supplier) { - return 1 - } - if (a.supplier === b.supplier) { - if (a.id > b.id) { - return 1 - } - return -1 - } - return -1 - }) -} - -export function findGraphData(sizeFractions: number[], bridges: Bridge): GraphData[] { - const newGraphData: GraphData[] = [] - sizeFractions.forEach((fraction, sizeIndex) => { - const temp: GraphData = { size: fraction } - Object.entries(bridges).forEach(([name, cumulative]) => { - temp[name] = cumulative[sizeIndex] - }) - newGraphData.push(temp) - }) - return newGraphData -} +import type { GraphData } from '../types' function linearInterpolation(yMin: number, yMax: number, xMin: number, xMax: number, targetY: number): number { const increase = (yMax - yMin) / (xMax - xMin) diff --git a/web/src/lib/utils/findGraphData.ts b/web/src/lib/utils/findGraphData.ts new file mode 100644 index 00000000..ae2de530 --- /dev/null +++ b/web/src/lib/utils/findGraphData.ts @@ -0,0 +1,13 @@ +import type { Bridge, GraphData } from '../types' + +export function findGraphData(sizeFractions: number[], bridges: Bridge): GraphData[] { + const newGraphData: GraphData[] = [] + sizeFractions.forEach((fraction, sizeIndex) => { + const temp: GraphData = { size: fraction } + Object.entries(bridges).forEach(([name, cumulative]) => { + temp[name] = cumulative[sizeIndex] + }) + newGraphData.push(temp) + }) + return newGraphData +} diff --git a/web/src/lib/utils/sortProducts.ts b/web/src/lib/utils/sortProducts.ts new file mode 100644 index 00000000..b64947ee --- /dev/null +++ b/web/src/lib/utils/sortProducts.ts @@ -0,0 +1,16 @@ +import type { Product } from '../types' + +export function sortProducts(products: Array): Array { + return products.sort((a, b) => { + if (a.supplier > b.supplier) { + return 1 + } + if (a.supplier === b.supplier) { + if (a.id > b.id) { + return 1 + } + return -1 + } + return -1 + }) +} diff --git a/web/src/main.tsx b/web/src/main.tsx index 21b1f28e..27de6e6c 100644 --- a/web/src/main.tsx +++ b/web/src/main.tsx @@ -1,22 +1,7 @@ import { createRoot } from 'react-dom/client' import './index.css' -import { AuthProvider, type TAuthConfig } from 'react-oauth2-code-pkce' -import App from './App' - -const authConfig: TAuthConfig = { - clientId: import.meta.env.VITE_CLIENT_ID || '', - authorizationEndpoint: 'https://login.microsoftonline.com/3aa4a235-b6e2-48d5-9195-7fcf05b459b0/oauth2/v2.0/authorize', - tokenEndpoint: 'https://login.microsoftonline.com/3aa4a235-b6e2-48d5-9195-7fcf05b459b0/oauth2/v2.0/token', - redirectUri: window.location.origin, - scope: import.meta.env.VITE_SCOPES, - onRefreshTokenExpire: (event) => - window.confirm('Session expired. Refresh page to continue using the site?') && event.login(), -} +import { App } from './App' const container = document.getElementById('root') as HTMLElement const root = createRoot(container) -root.render( - - - -) +root.render() diff --git a/web/src/react-app-env.d.ts b/web/src/react-app-env.d.ts deleted file mode 100644 index 6431bc5f..00000000 --- a/web/src/react-app-env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// diff --git a/web/tsconfig.json b/web/tsconfig.json index f1443c44..be9ce51c 100644 --- a/web/tsconfig.json +++ b/web/tsconfig.json @@ -1,7 +1,7 @@ { "include": ["src"], "compilerOptions": { - "strict": false, + "strict": true, "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "target": "ES2020", "useDefineForClassFields": true, diff --git a/web/vite.config.ts b/web/vite.config.ts index 522c2c03..43bf0bcd 100644 --- a/web/vite.config.ts +++ b/web/vite.config.ts @@ -16,7 +16,13 @@ export default defineConfig({ 'img-src': ["'self'", 'data:'], 'object-src': ["'none'"], 'font-src': ["'self'", 'https://*.equinor.com'], - 'connect-src': ["'self'", 'https://*.microsoftonline.com'], + 'frame-ancestors': ["'none'"], + 'connect-src': [ + "'self'", + 'https://*.microsoftonline.com', + 'https://*.applicationinsights.azure.com', + 'https://*.monitor.azure.com', + ], }, build: { sri: true, @@ -27,6 +33,12 @@ export default defineConfig({ server: { port: 3000, host: true, + watch: { + usePolling: process.env.USE_POLLING === 'true', + }, + hmr: { + clientPort: process.env.HMR_CLIENT_PORT ? Number(process.env.HMR_CLIENT_PORT) : undefined, + }, }, build: { outDir: 'build',