diff --git a/.eslintrc.cjs b/.eslintrc.cjs
new file mode 100644
index 00000000..4746db02
--- /dev/null
+++ b/.eslintrc.cjs
@@ -0,0 +1,26 @@
+module.exports = {
+ env: {
+ node: true,
+ browser: true,
+ es6: true,
+ },
+ extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
+ parser: '@typescript-eslint/parser',
+ parserOptions: {
+ ecmaVersion: 'latest',
+ sourceType: 'module',
+ },
+ ignorePatterns: ['dist/', 'node_modules/', '*.gen.ts'],
+ plugins: ['@typescript-eslint', 'unused-imports', '@stylistic/ts'],
+ rules: {
+ '@typescript-eslint/member-ordering': 'error',
+ '@typescript-eslint/ban-ts-comment': 'off', // "move fast" mode
+ '@typescript-eslint/no-explicit-any': 'off', // "move fast" mode
+ 'linebreak-style': ['error', 'unix'],
+ 'unused-imports/no-unused-imports': 'error',
+ // No double quotes
+ quotes: ['error', 'single', { avoidEscape: true }],
+ // No extra semicolon
+ '@stylistic/ts/semi': ['error', 'never'],
+ },
+}
diff --git a/.github/scripts/is_release_for_package.sh b/.github/scripts/is_release_for_package.sh
new file mode 100755
index 00000000..c8965efb
--- /dev/null
+++ b/.github/scripts/is_release_for_package.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+# This script checks if the specified package has changesets in the current commit.
+
+set -eu
+
+if [ $# -lt 1 ]; then
+ echo "Error: Package name is required as the first argument." >&2
+ exit 1
+fi
+
+PACKAGE_NAME=$1
+PACKAGE_CHANGES=$(node -e "require('@changesets/read').default(process.cwd()).then(result => console.log(result.flatMap(changeset => changeset.releases.flatMap(release => release.name)).includes('${PACKAGE_NAME}')))")
+
+echo "${PACKAGE_CHANGES}"
diff --git a/.github/workflows/build_prod_template.yml b/.github/workflows/build_prod_template.yml
new file mode 100644
index 00000000..da3424b0
--- /dev/null
+++ b/.github/workflows/build_prod_template.yml
@@ -0,0 +1,110 @@
+name: Build Prod Template
+
+on:
+ workflow_dispatch:
+ inputs:
+ target_environment:
+ description: Target environment
+ required: true
+ type: choice
+ default: foxtrot
+ options:
+ - foxtrot
+ - staging
+ - juliett
+ skip_cache:
+ description: Skip build cache
+ required: false
+ type: boolean
+ default: false
+
+concurrency:
+ group: Release-${{ github.ref }}-${{ inputs.target_environment }}
+ cancel-in-progress: false
+
+permissions:
+ contents: read
+
+jobs:
+ build-template:
+ name: Build E2B template
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Parse .tool-versions
+ uses: wistia/parse-tool-versions@v2.1.1
+ with:
+ filename: '.tool-versions'
+ uppercase: 'true'
+ prefix: 'tool_version_'
+
+ - uses: actions/setup-python@v6
+ with:
+ python-version: '${{ env.TOOL_VERSION_PYTHON }}'
+
+ - name: Install development dependencies
+ working-directory: ./template
+ run: pip install -r requirements-dev.txt
+
+ - name: Resolve target environment
+ env:
+ TARGET_ENVIRONMENT: ${{ inputs.target_environment }}
+ FOXTROT_DOMAIN: ${{ vars.E2B_DOMAIN }}
+ FOXTROT_API_KEY: ${{ secrets.E2B_PROD_API_KEY }}
+ STAGING_API_KEY: ${{ secrets.E2B_STAGING_API_KEY }}
+ JULIETT_API_KEY: ${{ secrets.E2B_JULIETT_API_KEY }}
+ run: |
+ set -eu
+
+ case "$TARGET_ENVIRONMENT" in
+ foxtrot)
+ E2B_DOMAIN="$FOXTROT_DOMAIN"
+ E2B_API_KEY="$FOXTROT_API_KEY"
+ ;;
+ staging)
+ E2B_DOMAIN="e2b-staging.dev"
+ E2B_API_KEY="$STAGING_API_KEY"
+ ;;
+ juliett)
+ E2B_DOMAIN="e2b-juliett.dev"
+ E2B_API_KEY="$JULIETT_API_KEY"
+ ;;
+ *)
+ echo "Unknown target environment: $TARGET_ENVIRONMENT" >&2
+ exit 1
+ ;;
+ esac
+
+ if [ -z "$E2B_DOMAIN" ]; then
+ echo "Missing E2B domain for target environment: $TARGET_ENVIRONMENT" >&2
+ exit 1
+ fi
+
+ if [ -z "$E2B_API_KEY" ]; then
+ echo "Missing API key secret for target environment: $TARGET_ENVIRONMENT" >&2
+ exit 1
+ fi
+
+ echo "::add-mask::$E2B_API_KEY"
+
+ {
+ echo "E2B_DOMAIN=$E2B_DOMAIN"
+ echo "E2B_API_KEY=$E2B_API_KEY"
+ } >> "$GITHUB_ENV"
+
+ {
+ echo "### Build target"
+ echo
+ echo "Target: $TARGET_ENVIRONMENT"
+ echo "Domain: $E2B_DOMAIN"
+ } >> "$GITHUB_STEP_SUMMARY"
+
+ - name: Build E2B template
+ id: build-template
+ working-directory: ./template
+ run: |
+ python build_prod.py
+ env:
+ SKIP_CACHE: ${{ inputs.skip_cache }}
diff --git a/.github/workflows/build_test_template.yml b/.github/workflows/build_test_template.yml
new file mode 100644
index 00000000..348001e0
--- /dev/null
+++ b/.github/workflows/build_test_template.yml
@@ -0,0 +1,67 @@
+name: Build Template
+
+on:
+ workflow_call:
+ secrets:
+ E2B_API_KEY:
+ required: true
+ inputs:
+ E2B_DOMAIN:
+ required: false
+ type: string
+ outputs:
+ template_id:
+ description: "The ID of the built template"
+ value: ${{ jobs.build.outputs.template_id }}
+
+permissions:
+ contents: read
+
+jobs:
+ build:
+ name: Build E2B Template
+ runs-on: ubuntu-latest
+ outputs:
+ template_id: ${{ steps.build-template.outputs.template_id }}
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Parse .tool-versions
+ uses: wistia/parse-tool-versions@v2.1.1
+ with:
+ filename: '.tool-versions'
+ uppercase: 'true'
+ prefix: 'tool_version_'
+
+ - name: Set package version
+ working-directory: ./template
+ run: |
+ VERSION=$(cat ../chart_data_extractor/pyproject.toml | grep version | cut -d '"' -f 2)
+ echo "Version: $VERSION"
+ sed -i "s/e2b_charts/e2b_charts==${VERSION}/g" requirements.txt
+
+ - uses: actions/setup-python@v6
+ with:
+ python-version: '${{ env.TOOL_VERSION_PYTHON }}'
+
+ - name: Install development dependencies
+ working-directory: ./template
+ run: pip install -r requirements-dev.txt
+
+ - name: Generate Template Name
+ id: generate-template-id
+ run: |
+ E2B_TESTS_TEMPLATE=e2b-code-interpreter-ci-$(uuidgen)
+ echo "Generated Template Name: $E2B_TESTS_TEMPLATE"
+ echo "template_name=$E2B_TESTS_TEMPLATE" >> $GITHUB_OUTPUT
+
+ - name: Build E2B template
+ id: build-template
+ working-directory: ./template
+ run: |
+ python build_ci.py
+ env:
+ E2B_API_KEY: ${{ secrets.E2B_API_KEY }}
+ E2B_DOMAIN: ${{ inputs.E2B_DOMAIN }}
+ E2B_TESTS_TEMPLATE: ${{ steps.generate-template-id.outputs.template_name }}
diff --git a/.github/workflows/charts_tests.yml b/.github/workflows/charts_tests.yml
new file mode 100644
index 00000000..f2837786
--- /dev/null
+++ b/.github/workflows/charts_tests.yml
@@ -0,0 +1,47 @@
+name: Test Python SDK
+
+on:
+ workflow_call:
+
+permissions:
+ contents: read
+
+jobs:
+ publish:
+ defaults:
+ run:
+ working-directory: ./chart_data_extractor
+ name: Chart Data Extractor - Build and test
+ runs-on: ubuntu-22.04
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Parse .tool-versions
+ uses: wistia/parse-tool-versions@v2.1.1
+ with:
+ filename: '.tool-versions'
+ uppercase: 'true'
+ prefix: 'tool_version_'
+
+ - name: Set up Python
+ uses: actions/setup-python@v6
+ with:
+ python-version: '${{ env.TOOL_VERSION_PYTHON }}'
+
+ - name: Install and configure Poetry
+ uses: snok/install-poetry@v1
+ with:
+ version: '${{ env.TOOL_VERSION_POETRY }}'
+ virtualenvs-create: true
+ virtualenvs-in-project: true
+ installer-parallel: true
+
+ - name: Install dependencies
+ run: poetry install
+
+ - name: Test build
+ run: poetry build
+
+ - name: Run tests
+ run: poetry run pytest --verbose -x
diff --git a/.github/workflows/cleanup_build_template.yml b/.github/workflows/cleanup_build_template.yml
new file mode 100644
index 00000000..9878474c
--- /dev/null
+++ b/.github/workflows/cleanup_build_template.yml
@@ -0,0 +1,33 @@
+name: Cleanup Build Template
+
+on:
+ workflow_call:
+ secrets:
+ E2B_TESTS_ACCESS_TOKEN:
+ required: true
+ inputs:
+ E2B_DOMAIN:
+ required: false
+ type: string
+ E2B_TESTS_TEMPLATE:
+ required: true
+ type: string
+
+permissions:
+ contents: read
+
+jobs:
+ cleanup:
+ name: Cleanup Build Template
+ runs-on: ubuntu-latest
+ steps:
+ - name: Install E2B CLI
+ run: npm install -g @e2b/cli
+
+ - name: Cleanup E2B template
+ id: cleanup-template
+ run: |
+ e2b template delete -y "${{ inputs.E2B_TESTS_TEMPLATE }}"
+ env:
+ E2B_ACCESS_TOKEN: ${{ secrets.E2B_TESTS_ACCESS_TOKEN }}
+ E2B_DOMAIN: ${{ inputs.E2B_DOMAIN }}
diff --git a/.github/workflows/js_tests.yml b/.github/workflows/js_tests.yml
index 9244926f..43eb551b 100644
--- a/.github/workflows/js_tests.yml
+++ b/.github/workflows/js_tests.yml
@@ -5,32 +5,39 @@ on:
secrets:
E2B_API_KEY:
required: true
+ inputs:
+ E2B_DOMAIN:
+ required: false
+ type: string
+ E2B_TESTS_TEMPLATE:
+ required: false
+ type: string
permissions:
contents: read
jobs:
- publish:
+ test:
defaults:
run:
working-directory: ./js
- name: Build and test SDK
- runs-on: ubuntu-20.04
+ name: JS SDK - Build and test
+ runs-on: ubuntu-22.04
steps:
- name: Checkout repository
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Install pnpm
- uses: pnpm/action-setup@v2
+ uses: pnpm/action-setup@v3
id: pnpm-install
with:
- version: 8
+ version: 9.5
- name: Setup Node
uses: actions/setup-node@v3
with:
- node-version: '18.x'
- registry-url: 'https://registry.npmjs.org'
+ node-version: "20.x"
+ registry-url: "https://registry.npmjs.org"
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
@@ -45,7 +52,33 @@ jobs:
- name: Test build
run: pnpm build
- - name: Run node tests
- run: pnpm run test
+ - name: Run Node tests
+ run: pnpm test
env:
E2B_API_KEY: ${{ secrets.E2B_API_KEY }}
+ E2B_DOMAIN: ${{ vars.E2B_DOMAIN }}
+ E2B_TESTS_TEMPLATE: ${{ inputs.E2B_TESTS_TEMPLATE }}
+
+ - name: Install Bun
+ uses: oven-sh/setup-bun@v2
+ with:
+ bun-version: 1.3.14
+
+ - name: Run Bun tests
+ run: pnpm test:bun
+ env:
+ E2B_API_KEY: ${{ secrets.E2B_API_KEY }}
+ E2B_DOMAIN: ${{ vars.E2B_DOMAIN }}
+ E2B_TESTS_TEMPLATE: ${{ inputs.E2B_TESTS_TEMPLATE }}
+
+ - name: Install Deno
+ uses: denoland/setup-deno@v2
+ with:
+ deno-version: v2.x
+
+ - name: Run Deno tests
+ run: pnpm test:deno
+ env:
+ E2B_API_KEY: ${{ secrets.E2B_API_KEY }}
+ E2B_DOMAIN: ${{ vars.E2B_DOMAIN }}
+ E2B_TESTS_TEMPLATE: ${{ inputs.E2B_TESTS_TEMPLATE }}
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
new file mode 100644
index 00000000..08beb345
--- /dev/null
+++ b/.github/workflows/lint.yml
@@ -0,0 +1,79 @@
+name: Lint
+
+on:
+ pull_request:
+
+permissions:
+ contents: read
+
+jobs:
+ lint:
+ name: Lint
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repo
+ uses: actions/checkout@v4
+
+ - name: Parse .tool-versions
+ uses: wistia/parse-tool-versions@v2.1.1
+ with:
+ filename: '.tool-versions'
+ uppercase: 'true'
+ prefix: 'tool_version_'
+
+ - uses: pnpm/action-setup@v4
+ with:
+ version: 9.15.9
+
+ - name: Setup Node.js 20
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20.x'
+ cache: pnpm
+
+ - name: Configure pnpm
+ run: |
+ pnpm config set auto-install-peers true
+ pnpm config set exclude-links-from-lockfile true
+
+ - name: Install dependencies
+ run: pnpm install --frozen-lockfile
+
+ - name: Set up Python
+ uses: actions/setup-python@v6
+ with:
+ python-version: '${{ env.TOOL_VERSION_PYTHON }}'
+
+ - name: Install and configure Poetry
+ uses: snok/install-poetry@v1
+ with:
+ version: '${{ env.TOOL_VERSION_POETRY }}'
+ virtualenvs-create: true
+ virtualenvs-in-project: true
+ installer-parallel: true
+
+ - name: Install Python dependencies
+ working-directory: python
+ run: |
+ poetry install --with dev
+ pip install ruff=="0.11.12"
+
+ - name: Run linting
+ run: |
+ pnpm run lint
+
+ - name: Run formatting
+ run: |
+ pnpm run format
+
+ - name: Check for uncommitted changes
+ run: |
+ if [[ -n $(git status --porcelain) ]]; then
+ echo "❌ Files are not formatted properly:"
+ git status --short
+ git diff
+ exit 1
+ else
+ echo "✅ No changes detected."
+ fi
\ No newline at end of file
diff --git a/.github/workflows/performance_tests.yml b/.github/workflows/performance_tests.yml
new file mode 100644
index 00000000..a0f20aa5
--- /dev/null
+++ b/.github/workflows/performance_tests.yml
@@ -0,0 +1,70 @@
+name: Performance tests
+
+on:
+ workflow_call:
+ secrets:
+ E2B_API_KEY:
+ required: true
+ inputs:
+ E2B_DOMAIN:
+ required: false
+ type: string
+ E2B_TESTS_TEMPLATE:
+ required: false
+ type: string
+ E2B_TESTS_BENCHMARK_ITERATIONS_COUNT:
+ required: false
+ type: number
+ default: 20
+
+permissions:
+ contents: read
+
+jobs:
+ performance-tests:
+ defaults:
+ run:
+ working-directory: ./python
+ name: Performance tests
+ runs-on: ubuntu-22.04
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Parse .tool-versions
+ uses: wistia/parse-tool-versions@v2.1.1
+ with:
+ filename: '.tool-versions'
+ uppercase: 'true'
+ prefix: 'tool_version_'
+
+ - name: Set up Python
+ uses: actions/setup-python@v6
+ with:
+ python-version: '${{ env.TOOL_VERSION_PYTHON }}'
+
+ - name: Install and configure Poetry
+ uses: snok/install-poetry@v1
+ with:
+ version: '${{ env.TOOL_VERSION_POETRY }}'
+ virtualenvs-create: true
+ virtualenvs-in-project: true
+ installer-parallel: true
+
+ - name: Install dependencies
+ run: poetry install
+
+ - name: Run performance tests
+ run: poetry run python tests/performance.py
+ env:
+ E2B_API_KEY: ${{ secrets.E2B_API_KEY }}
+ E2B_DOMAIN: ${{ inputs.E2B_DOMAIN }}
+ E2B_TESTS_TEMPLATE: ${{ inputs.E2B_TESTS_TEMPLATE }}
+ E2B_TESTS_BENCHMARK_ITERATIONS_COUNT: ${{ inputs.E2B_TESTS_BENCHMARK_ITERATIONS_COUNT }}
+ - name: Upload performance plot artifact
+ uses: actions/upload-artifact@v4
+ if: always()
+ with:
+ name: performance-plot-${{ github.run_number }}
+ path: ./python/performance_plot.png
+ retention-days: 30
\ No newline at end of file
diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml
deleted file mode 100644
index 1e7c8fed..00000000
--- a/.github/workflows/pr.yml
+++ /dev/null
@@ -1,53 +0,0 @@
-name: Test Python package
-
-on:
- push:
- branches-ignore:
- - main
-
-jobs:
- changes:
- name: Repository changes
- runs-on: ubuntu-latest
- outputs:
- python: ${{ steps.filter.outputs.python }}
- steps:
- - name: Checkout repository
- uses: actions/checkout@v3
- with:
- fetch-depth: 0
-
- - name: Get the last release
- id: last_release
- uses: cardinalby/git-get-release-action@v1
- env:
- GITHUB_TOKEN: ${{ github.token }}
- with:
- latest: true
- prerelease: false
- draft: false
-
- - name: Find changes since the last release
- uses: dorny/paths-filter@v2
- id: filter
- with:
- base: ${{ steps.last_release.outputs.tag_name }}
- filters: |
- python:
- - 'python/**'
- js:
- - 'js/**'
-
- python-tests:
- needs: [ changes ]
- name: Tests Python package
- if: needs.changes.outputs.python == 'true'
- uses: ./.github/workflows/python_tests.yml
- secrets: inherit
-
- js-tests:
- needs: [ changes ]
- name: Tests JS package
- if: needs.changes.outputs.js == 'true'
- uses: ./.github/workflows/js_tests.yml
- secrets: inherit
diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml
new file mode 100644
index 00000000..7ed194c9
--- /dev/null
+++ b/.github/workflows/pull_request.yml
@@ -0,0 +1,57 @@
+name: Pull Request
+
+permissions:
+ contents: read
+ id-token: write
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+on:
+ pull_request:
+ branches:
+ - main
+
+jobs:
+ build-template:
+ uses: ./.github/workflows/build_test_template.yml
+ secrets:
+ E2B_API_KEY: ${{ secrets.E2B_API_KEY }}
+ with:
+ E2B_DOMAIN: ${{ vars.E2B_DOMAIN }}
+ js-sdk:
+ uses: ./.github/workflows/js_tests.yml
+ needs: build-template
+ secrets:
+ E2B_API_KEY: ${{ secrets.E2B_API_KEY }}
+ with:
+ E2B_DOMAIN: ${{ vars.E2B_DOMAIN }}
+ E2B_TESTS_TEMPLATE: ${{ needs.build-template.outputs.template_id }}
+ python-sdk:
+ uses: ./.github/workflows/python_tests.yml
+ needs: build-template
+ secrets:
+ E2B_API_KEY: ${{ secrets.E2B_API_KEY }}
+ with:
+ E2B_DOMAIN: ${{ vars.E2B_DOMAIN }}
+ E2B_TESTS_TEMPLATE: ${{ needs.build-template.outputs.template_id }}
+ performance-tests:
+ uses: ./.github/workflows/performance_tests.yml
+ needs: build-template
+ secrets:
+ E2B_API_KEY: ${{ secrets.E2B_API_KEY }}
+ with:
+ E2B_DOMAIN: ${{ vars.E2B_DOMAIN }}
+ E2B_TESTS_TEMPLATE: ${{ needs.build-template.outputs.template_id }}
+ cleanup-build-template:
+ uses: ./.github/workflows/cleanup_build_template.yml
+ needs: [build-template, js-sdk, python-sdk, performance-tests]
+ if: always() && !contains(needs.build-template.result, 'failure') && !contains(needs.build-template.result, 'cancelled')
+ secrets:
+ E2B_TESTS_ACCESS_TOKEN: ${{ secrets.E2B_TESTS_ACCESS_TOKEN }}
+ with:
+ E2B_DOMAIN: ${{ vars.E2B_DOMAIN }}
+ E2B_TESTS_TEMPLATE: ${{ needs.build-template.outputs.template_id }}
+ charts-tests:
+ uses: ./.github/workflows/charts_tests.yml
diff --git a/.github/workflows/python_tests.yml b/.github/workflows/python_tests.yml
index dd63624a..8149c91c 100644
--- a/.github/workflows/python_tests.yml
+++ b/.github/workflows/python_tests.yml
@@ -5,6 +5,13 @@ on:
secrets:
E2B_API_KEY:
required: true
+ inputs:
+ E2B_DOMAIN:
+ required: false
+ type: string
+ E2B_TESTS_TEMPLATE:
+ required: false
+ type: string
permissions:
contents: read
@@ -14,21 +21,28 @@ jobs:
defaults:
run:
working-directory: ./python
- name: Build and test SDK
- runs-on: ubuntu-20.04
+ name: Python SDK - Build and test
+ runs-on: ubuntu-22.04
steps:
- name: Checkout repository
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
+
+ - name: Parse .tool-versions
+ uses: wistia/parse-tool-versions@v2.1.1
+ with:
+ filename: '.tool-versions'
+ uppercase: 'true'
+ prefix: 'tool_version_'
- name: Set up Python
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v6
with:
- python-version: '3.8'
+ python-version: '${{ env.TOOL_VERSION_PYTHON }}'
- name: Install and configure Poetry
uses: snok/install-poetry@v1
with:
- version: 1.5.1
+ version: '${{ env.TOOL_VERSION_POETRY }}'
virtualenvs-create: true
virtualenvs-in-project: true
installer-parallel: true
@@ -43,3 +57,5 @@ jobs:
run: poetry run pytest --verbose -x
env:
E2B_API_KEY: ${{ secrets.E2B_API_KEY }}
+ E2B_DOMAIN: ${{ inputs.E2B_DOMAIN }}
+ E2B_TESTS_TEMPLATE: ${{ inputs.E2B_TESTS_TEMPLATE }}
\ No newline at end of file
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 06fa3b7d..84b5d3a6 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -5,9 +5,10 @@ on:
branches:
- main
-concurrency: ${{ github.workflow }}-${{ github.ref }}
+concurrency: Release-${{ github.ref }}-foxtrot
permissions:
+ id-token: write
contents: write
jobs:
@@ -18,18 +19,18 @@ jobs:
release: ${{ steps.version.outputs.release }}
steps:
- name: Checkout Repo
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Install pnpm
- uses: pnpm/action-setup@v2
+ uses: pnpm/action-setup@v3
id: pnpm-install
with:
- version: 8
+ version: 9.5
- name: Setup Node
- uses: actions/setup-node@v3
+ uses: actions/setup-node@v6
with:
- node-version: "18.x"
+ node-version: "22.x"
registry-url: "https://registry.npmjs.org"
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
@@ -54,77 +55,287 @@ jobs:
if: needs.is_release.outputs.release == 'true'
runs-on: ubuntu-latest
outputs:
- js: ${{ steps.filter.outputs.js }}
- python: ${{ steps.filter.outputs.python }}
+ js: ${{ steps.js.outputs.release }}
+ python: ${{ steps.python.outputs.release }}
+ charts: ${{ steps.charts.outputs.release }}
+ template: ${{ steps.template.outputs.release }}
steps:
- - name: Checkout repository
- uses: actions/checkout@v3
+ - name: Checkout Repo
+ uses: actions/checkout@v4
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v3
+ id: pnpm-install
+ with:
+ version: 9.5
+
+ - name: Setup Node
+ uses: actions/setup-node@v6
with:
- fetch-depth: 0
+ node-version: "22.x"
+ registry-url: "https://registry.npmjs.org"
+ cache: pnpm
+ cache-dependency-path: pnpm-lock.yaml
+
+ - name: Configure pnpm
+ run: |
+ pnpm config set auto-install-peers true
+ pnpm config set exclude-links-from-lockfile true
+
+ - name: Install dependencies
+ run: pnpm install --frozen-lockfile
+
+ - name: Check JavasScript SDK Release
+ id: js
+ run: |
+ IS_RELEASE=$(./.github/scripts/is_release_for_package.sh "@e2b/code-interpreter")
+ echo "release=$IS_RELEASE" >> "$GITHUB_OUTPUT"
+
+ - name: Check Python SDK Release
+ id: python
+ run: |
+ IS_RELEASE=$(./.github/scripts/is_release_for_package.sh "@e2b/code-interpreter-python")
+ echo "release=$IS_RELEASE" >> "$GITHUB_OUTPUT"
+
+ - name: Check Charts SDK Release
+ id: charts
+ run: |
+ IS_RELEASE=$(./.github/scripts/is_release_for_package.sh "@e2b/data-extractor")
+ echo "release=$IS_RELEASE" >> "$GITHUB_OUTPUT"
+
+ - name: Check Template SDK Release
+ id: template
+ run: |
+ IS_RELEASE=$(./.github/scripts/is_release_for_package.sh "@e2b/code-interpreter-template")
+ echo "release=$IS_RELEASE" >> "$GITHUB_OUTPUT"
+
+ charts-release:
+ name: Charts release
+ needs: [changes]
+ if: needs.changes.outputs.charts == 'true'
+ runs-on: ubuntu-latest
+ outputs:
+ version: ${{ steps.output_version.outputs.version }}
+ steps:
+ - name: Checkout Repo
+ uses: actions/checkout@v4
+
+ - name: Parse .tool-versions
+ uses: wistia/parse-tool-versions@v2.1.1
+ with:
+ filename: '.tool-versions'
+ uppercase: 'true'
+ prefix: 'tool_version_'
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v3
+ id: pnpm-install
+ with:
+ version: 9.5
+
+ - name: Set up Python
+ uses: actions/setup-python@v6
+ with:
+ python-version: '${{ env.TOOL_VERSION_PYTHON }}'
+
+ - name: Install and configure Poetry
+ uses: snok/install-poetry@v1
+ with:
+ version: '${{ env.TOOL_VERSION_POETRY }}'
+ virtualenvs-create: true
+ virtualenvs-in-project: true
+ installer-parallel: true
- - name: Get the last release
- id: last_release
- uses: cardinalby/git-get-release-action@v1
+ - name: Configure pnpm
+ run: |
+ pnpm config set auto-install-peers true
+ pnpm config set exclude-links-from-lockfile true
+
+ - name: Install dependencies
+ run: pnpm install --frozen-lockfile
+
+ - name: Create new versions
+ run: pnpm run version
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Release new versions
+ run: |
+ poetry build
+ poetry config pypi-token.pypi ${PYPI_TOKEN}
+ poetry publish --skip-existing
+ working-directory: ./chart_data_extractor
env:
- GITHUB_TOKEN: ${{ github.token }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ PYPI_TOKEN: ${{ secrets.CHARTS_PYPI_TOKEN }}
+
+ - name: Output new version
+ id: output_version
+ working-directory: ./chart_data_extractor
+ run: |
+ echo "::set-output name=version::$(pnpm pkg get version --workspaces=false | tr -d \\\")"
+
+ build-docker-image:
+ name: Build Docker Image
+ runs-on: ubuntu-latest
+ needs: [changes, charts-release]
+ if: always() &&
+ !contains(needs.*.result, 'failure') &&
+ !contains(needs.*.result, 'cancelled') &&
+ (needs.changes.outputs.template == 'true' || needs.changes.outputs.charts == 'true')
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Parse .tool-versions
+ uses: wistia/parse-tool-versions@v2.1.1
+ with:
+ filename: '.tool-versions'
+ uppercase: 'true'
+ prefix: 'tool_version_'
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+
+ - name: Log in to DockerHub
+ uses: docker/login-action@v3
with:
- latest: true
- prerelease: false
- draft: false
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
- - name: Find changes since the last release
- uses: dorny/paths-filter@v2
- id: filter
+ - name: Set package version
+ working-directory: ./template
+ run: |
+ if [ -z "${{ needs.charts-release.outputs.version }}" ]; then
+ VERSION=$(cat ../chart_data_extractor/pyproject.toml | grep version | cut -d '"' -f 2)
+ else
+ VERSION=${{ needs.charts-release.outputs.version }}
+ fi
+ echo "Version: $VERSION"
+
+ sed -i "s/e2b_charts/e2b_charts==${VERSION}/g" requirements.txt
+
+ - uses: actions/setup-python@v6
+ with:
+ python-version: '${{ env.TOOL_VERSION_PYTHON }}'
+
+ - name: Install development dependencies
+ working-directory: ./template
+ run: pip install -r requirements-dev.txt
+
+ - name: Build and push to DockerHub
+ working-directory: ./template
+ run: |
+ python build_docker.py | docker buildx build \
+ --platform linux/amd64 \
+ --push \
+ --tag ${{ secrets.DOCKERHUB_USERNAME }}/code-interpreter:latest -f - .
+
+ build-template:
+ name: Build E2B template
+ runs-on: ubuntu-latest
+ needs: [build-docker-image]
+ if: always() &&
+ !contains(needs.*.result, 'failure') &&
+ !contains(needs.*.result, 'cancelled') &&
+ (needs.changes.outputs.template == 'true' || needs.changes.outputs.charts == 'true')
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Parse .tool-versions
+ uses: wistia/parse-tool-versions@v2.1.1
+ with:
+ filename: '.tool-versions'
+ uppercase: 'true'
+ prefix: 'tool_version_'
+
+ - uses: actions/setup-python@v6
with:
- base: ${{ steps.last_release.outputs.tag_name }}
- filters: |
- js:
- - 'js/**'
- python:
- - 'python/**'
+ python-version: '${{ env.TOOL_VERSION_PYTHON }}'
+
+ - name: Install development dependencies
+ working-directory: ./template
+ run: pip install -r requirements-dev.txt
+
+ - name: Build E2B template
+ id: build-template
+ working-directory: ./template
+ run: |
+ python build_prod.py
+ env:
+ E2B_API_KEY: ${{ secrets.E2B_PROD_API_KEY }}
+ E2B_DOMAIN: ${{ vars.E2B_DOMAIN }}
python-tests:
name: Python Tests
- needs: [changes]
- if: needs.changes.outputs.python == 'true'
+ needs: [changes, build-template]
+ if: always() &&
+ !contains(needs.*.result, 'failure') &&
+ !contains(needs.*.result, 'cancelled') &&
+ needs.changes.outputs.template == 'true'
uses: ./.github/workflows/python_tests.yml
secrets: inherit
js-tests:
name: JS Tests
- needs: [changes]
- if: needs.changes.outputs.js == 'true'
+ needs: [changes, build-template]
+ if: always() &&
+ !contains(needs.*.result, 'failure') &&
+ !contains(needs.*.result, 'cancelled') &&
+ needs.changes.outputs.template == 'true'
uses: ./.github/workflows/js_tests.yml
secrets: inherit
release:
needs: [python-tests, js-tests]
- if: always() && !contains(needs.*.result, 'failure') && needs.is_release.outputs.release == 'true'
+ if: always() &&
+ !contains(needs.*.result, 'failure') &&
+ !contains(needs.*.result, 'cancelled') &&
+ (needs.changes.outputs.js == 'true' || needs.changes.outputs.python == 'true' || needs.changes.outputs.charts == 'true' || needs.changes.outputs.template == 'true')
name: Release
runs-on: ubuntu-latest
steps:
+ - uses: actions/create-github-app-token@v1
+ id: app-token
+ with:
+ app-id: ${{ vars.VERSION_BUMPER_APPID }}
+ private-key: ${{ secrets.VERSION_BUMPER_SECRET }}
+
- name: Checkout Repo
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
+ with:
+ token: ${{ steps.app-token.outputs.token }}
+
+ - name: Parse .tool-versions
+ uses: wistia/parse-tool-versions@v2.1.1
+ with:
+ filename: '.tool-versions'
+ uppercase: 'true'
+ prefix: 'tool_version_'
- name: Set up Python
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v6
with:
- python-version: "3.10"
+ python-version: '${{ env.TOOL_VERSION_PYTHON }}'
- name: Install and configure Poetry
uses: snok/install-poetry@v1
with:
- version: 1.8.1
+ version: '${{ env.TOOL_VERSION_POETRY }}'
virtualenvs-create: true
virtualenvs-in-project: true
installer-parallel: true
- - uses: pnpm/action-setup@v2
+ - uses: pnpm/action-setup@v3
+ with:
+ version: 9.5
- - name: Setup Node.js 20
- uses: actions/setup-node@v3
+ - name: Setup Node.js 24
+ uses: actions/setup-node@v6
with:
- node-version: 20
+ node-version: "24.x"
+ registry-url: 'https://registry.npmjs.org'
cache: pnpm
- name: Configure pnpm
@@ -147,7 +358,7 @@ jobs:
createGithubReleases: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
+ NPM_TOKEN: "" # See https://github.com/changesets/changesets/issues/1152#issuecomment-3190884868
PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }}
- name: Update lock file
@@ -175,3 +386,4 @@ jobs:
SLACK_MESSAGE: ":here-we-go-again: :bob-the-destroyer: We need :fix-parrot: ASAP :pray:"
SLACK_TITLE: Code Interpreter Release Failed
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
+ SLACK_CHANNEL: "monitoring-releases"
diff --git a/.github/workflows/release_candidates.yml b/.github/workflows/release_candidates.yml
index 911585e4..cd09fce4 100644
--- a/.github/workflows/release_candidates.yml
+++ b/.github/workflows/release_candidates.yml
@@ -17,14 +17,23 @@ jobs:
with:
ref: ${{ github.head_ref }}
+ - name: Parse .tool-versions
+ uses: wistia/parse-tool-versions@v2.1.1
+ with:
+ filename: '.tool-versions'
+ uppercase: 'true'
+ prefix: 'tool_version_'
+
- uses: pnpm/action-setup@v3
if: ${{ contains( github.event.pull_request.labels.*.name, 'js-rc') }}
+ with:
+ version: 9.5
- name: Setup Node.js 20
uses: actions/setup-node@v4
if: ${{ contains( github.event.pull_request.labels.*.name, 'js-rc') }}
with:
- node-version: 20
+ node-version: "20.x"
registry-url: https://registry.npmjs.org
cache: pnpm
@@ -38,6 +47,14 @@ jobs:
if: ${{ contains( github.event.pull_request.labels.*.name, 'js-rc') }}
run: pnpm install --frozen-lockfile
+ - name: Test JS SDK
+ working-directory: js
+ if: ${{ contains( github.event.pull_request.labels.*.name, 'js-rc') }}
+ run: |
+ pnpm run test
+ env:
+ E2B_API_KEY: ${{ secrets.E2B_API_KEY }}
+
- name: Release JS Candidate
working-directory: js
if: ${{ contains( github.event.pull_request.labels.*.name, 'js-rc') }}
@@ -48,20 +65,29 @@ jobs:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Set up Python
- uses: actions/setup-python@v4
+ uses: actions/setup-python@v6
if: ${{ contains( github.event.pull_request.labels.*.name, 'python-rc') }}
with:
- python-version: "3.10"
+ python-version: '${{ env.TOOL_VERSION_PYTHON }}'
- name: Install and configure Poetry
uses: snok/install-poetry@v1
if: ${{ contains( github.event.pull_request.labels.*.name, 'python-rc') }}
with:
- version: 1.8.1
+ version: '${{ env.TOOL_VERSION_POETRY }}'
virtualenvs-create: true
virtualenvs-in-project: true
installer-parallel: true
+ - name: Test Python SDK
+ if: ${{ contains( github.event.pull_request.labels.*.name, 'python-rc') }}
+ working-directory: python
+ run: |
+ poetry install
+ poetry run pytest -n 4 --verbose -x
+ env:
+ E2B_API_KEY: ${{ secrets.E2B_API_KEY }}
+
- name: Release Candidate
if: ${{ contains( github.event.pull_request.labels.*.name, 'python-rc') }}
working-directory: python
diff --git a/.github/workflows/template.yml b/.github/workflows/template.yml
deleted file mode 100644
index 1efbc57f..00000000
--- a/.github/workflows/template.yml
+++ /dev/null
@@ -1,50 +0,0 @@
-name: Build and push Code Interpreter template
-
-on:
- push:
- paths:
- - 'template/**'
- - '.github/workflows/template.yml'
- branches:
- - main
-
-permissions:
- contents: read
-
-jobs:
- buildAndPublish:
- defaults:
- run:
- working-directory: ./template
-
- name: Build and Push Images
- runs-on: ubuntu-20.04
- steps:
- - name: Checkout repository
- uses: actions/checkout@v3
-
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@v3
-
- - name: Log in to DockerHub
- uses: docker/login-action@v3
- with:
- username: ${{ secrets.DOCKERHUB_USERNAME }}
- password: ${{ secrets.DOCKERHUB_TOKEN }}
-
- - name: Build and push to DockerHub
- run: |
- docker pull ${{ secrets.DOCKERHUB_USERNAME }}/code-interpreter:latest || true
- docker buildx build \
- --file e2b.Dockerfile \
- --platform linux/amd64,linux/arm64 \
- --push \
- --tag ${{ secrets.DOCKERHUB_USERNAME }}/code-interpreter:latest .
-
- - name: Install E2B CLI
- run: npm install -g @e2b/cli
-
- - name: Build e2b
- run: e2b template build
- env:
- E2B_ACCESS_TOKEN: ${{ secrets.E2B_ACCESS_TOKEN }}
\ No newline at end of file
diff --git a/.github/workflows/validate-renovate-config.yaml b/.github/workflows/validate-renovate-config.yaml
new file mode 100644
index 00000000..a5feb8c6
--- /dev/null
+++ b/.github/workflows/validate-renovate-config.yaml
@@ -0,0 +1,19 @@
+name: validate renovate config
+
+permissions:
+ contents: read
+
+on:
+ pull_request:
+ branches:
+ - main
+
+jobs:
+ validate-renovate-config:
+ runs-on: ubuntu-24.04
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v6
+
+ - name: Validate Renovate config
+ uses: suzuki-shunsuke/github-action-renovate-config-validator@v2.0.0
diff --git a/.gitignore b/.gitignore
index a5c9d15f..b74489d7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -290,4 +290,6 @@ cython_debug/
.idea/
# VS Code
-.vscode/
\ No newline at end of file
+.vscode/
+
+.DS_Store
diff --git a/.npmrc b/.npmrc
index 700c82c9..4e82b99c 100644
--- a/.npmrc
+++ b/.npmrc
@@ -2,4 +2,5 @@ enable-pre-post-scripts=true
auto-install-peers=true
exclude-links-from-lockfile=true
prefer-workspace-packages=false
-link-workspace-packages=false
\ No newline at end of file
+link-workspace-packages=false
+engine-strict=true
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 00000000..bfbf1d05
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,8 @@
+/.next/
+
+# imporatant to keep // $HighlightLine comments at the end of the line
+apps/web/src/code/
+
+
+**/*.mdx
+**/code/**/*
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 00000000..0b495108
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,5 @@
+{
+ "singleQuote": true,
+ "semi": false,
+ "trailingComma": "es5"
+}
diff --git a/.tool-versions b/.tool-versions
new file mode 100644
index 00000000..d98d583a
--- /dev/null
+++ b/.tool-versions
@@ -0,0 +1,2 @@
+python 3.10
+poetry 1.8.5
diff --git a/CODEOWNERS b/CODEOWNERS
new file mode 100644
index 00000000..5f4fa93e
--- /dev/null
+++ b/CODEOWNERS
@@ -0,0 +1,3 @@
+# These owners will be the default owners for everything in
+# the repo. Unless a later match takes precedence.
+* @jakubno @ValentaTomas @mishushakov
diff --git a/Makefile b/Makefile
new file mode 100644
index 00000000..c1b25fea
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,8 @@
+start-template-server:
+ docker run --rm -e E2B_LOCAL=true -p 49999:49999 -it $$(python template/build_docker.py | docker build -q ./template -f -)
+
+kill-template-server:
+ docker kill $(shell docker ps --filter expose=49999 --format {{.ID}})
+
+debug-template:
+ cd template && python build_debug.py && python debug_logs.py
diff --git a/README.md b/README.md
index 9265d121..1b5216f9 100644
--- a/README.md
+++ b/README.md
@@ -1,77 +1,77 @@
-# Code Interpreter SDK
-E2B's [Code Interpreter SDK](https://github.com/e2b-dev/code-interpreter) allows you to add code interpreting capabilities to your AI apps.
-
-The code interpreter runs inside the [E2B Sandbox](https://github.com/e2b-dev/e2b) - an open-source secure sandbox made for running untrusted AI-generated code and AI agents.
-- ✅ Works with any LLM and AI framework
-- ✅ Supports streaming content like charts and stdout, stderr
-- ✅ Python & JS SDK
-- ✅ Runs on serverless and edge functions
-- ✅ Runs AI-generated code in secure sandboxed environments
-- ✅ 100% open source (including [infrastructure](https://github.com/e2b-dev/infra))
-
-Follow E2B on [X (Twitter)](https://twitter.com/e2b_dev).
-
-## 🚀 Quickstart
+
+
+
+
+
+
+
+
+## What is E2B?
+[E2B](https://www.e2b.dev/) is an open-source infrastructure that allows you to run AI-generated code in secure isolated sandboxes in the cloud. To start and control sandboxes, use our [JavaScript SDK](https://www.npmjs.com/package/@e2b/code-interpreter) or [Python SDK](https://pypi.org/project/e2b_code_interpreter).
+
+## Run your first Sandbox
### 1. Install SDK
-JavaScript/TypeScript
+JavaScript / TypeScript
```
npm i @e2b/code-interpreter
```
Python
```
-pip install e2b_code_interpreter
+pip install e2b-code-interpreter
```
-### 2. Execute code with code interpreter inside sandbox
+### 2. Get your E2B API key
+1. Sign up to E2B [here](https://e2b.dev).
+2. Get your API key [here](https://e2b.dev/dashboard?tab=keys).
+3. Set environment variable with your API key.
+```
+E2B_API_KEY=e2b_***
+```
-**JavaScript**
+### 3. Execute code with code interpreter inside Sandbox
+
+JavaScript / TypeScript
```ts
-import { CodeInterpreter } from '@e2b/code-interpreter'
+import { Sandbox } from '@e2b/code-interpreter'
-const sandbox = await CodeInterpreter.create()
-await sandbox.notebook.execCell('x = 1')
+const sbx = await Sandbox.create()
+await sbx.runCode('x = 1')
-const execution = await sandbox.notebook.execCell('x+=1; x')
+const execution = await sbx.runCode('x+=1; x')
console.log(execution.text) // outputs 2
-
-await sandbox.close()
```
-**Python**
+Python
```py
-from e2b_code_interpreter import CodeInterpreter
+from e2b_code_interpreter import Sandbox
-with CodeInterpreter() as sandbox:
- sandbox.notebook.exec_cell("x = 1")
-
- execution = sandbox.notebook.exec_cell("x+=1; x")
+with Sandbox.create() as sandbox:
+ sandbox.run_code("x = 1")
+ execution = sandbox.run_code("x+=1; x")
print(execution.text) # outputs 2
```
-### 3. Hello World guide
-Dive depeer and check out the [JavaScript](/hello-world/js) and [Python](/hello-world/py) the Hello World guides to learn how o connect code interpreter LLMs.
-
-
-## 📖 Cookbook examples
-
-**Hello World**
-- [TypeScript](https://github.com/e2b-dev/e2b-cookbook/tree/main/examples/hello-world-js)
-- [Python](https://github.com/e2b-dev/e2b-cookbook/tree/main/examples/hello-world-python)
-
-**LLM Providers**
-- 🪸 [Claude with code intepreter](https://github.com/e2b-dev/e2b-cookbook/blob/main/examples/claude-code-interpreter/claude_code_interpreter.ipynb)
-- 🦙 [Llama 3 with code interpreter](https://github.com/e2b-dev/e2b-cookbook/tree/main/examples/llama-3-code-interpreter)
-- [Mixtral with code interpreter and chat UI](https://github.com/e2b-dev/e2b-cookbook/tree/main/templates/mixtral-8x7b-code-interpreter-nextjs)
-
-**AI Frameworks**
-- 🦜⛓️ [LangChain with code interpreter](https://github.com/e2b-dev/e2b-cookbook/tree/main/examples/langchain-python)
-- 🦜🕸️ [LangGraph with code interpreter](https://github.com/e2b-dev/e2b-cookbook/tree/main/examples/langgraph-python)
-- [Autogen with secure sandboxed code interpreter](https://github.com/e2b-dev/e2b-cookbook/tree/main/examples/e2b_autogen)
+### 4. Check docs
+Visit [E2B documentation](https://e2b.dev/docs).
-## 💻 Supported languages for AI-code execution
-- ✅ Python
-- (soon) JavaScript/TypeScript
+### 5. E2B cookbook
+Visit our [Cookbook](https://github.com/e2b-dev/e2b-cookbook/tree/main) to get inspired by examples with different LLMs and AI frameworks.
+## Customizing the sandbox template
+Need extra packages or a different runtime? You can build your own Code Interpreter sandbox template. See the [template guide](/template/README.md) for a step-by-step walkthrough of creating, building, and using a custom template (as well as building the production `code-interpreter-v1` template).
diff --git a/chart_data_extractor/LICENSE b/chart_data_extractor/LICENSE
new file mode 100644
index 00000000..4aa6529d
--- /dev/null
+++ b/chart_data_extractor/LICENSE
@@ -0,0 +1,9 @@
+MIT License
+
+Copyright (c) 2025 FOUNDRYLABS, INC.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/chart_data_extractor/README.md b/chart_data_extractor/README.md
new file mode 100644
index 00000000..7c23e47f
--- /dev/null
+++ b/chart_data_extractor/README.md
@@ -0,0 +1,3 @@
+# Extracting Data for Code Interpreter SDK
+
+This package is a utility used to extract data in the Code Interpreter SDK from, e.g., DataFrames and matplotlib plots.
diff --git a/chart_data_extractor/e2b_charts/__init__.py b/chart_data_extractor/e2b_charts/__init__.py
new file mode 100644
index 00000000..adb4954c
--- /dev/null
+++ b/chart_data_extractor/e2b_charts/__init__.py
@@ -0,0 +1 @@
+from .main import chart_figure_to_chart, chart_figure_to_dict
diff --git a/chart_data_extractor/e2b_charts/charts/__init__.py b/chart_data_extractor/e2b_charts/charts/__init__.py
new file mode 100644
index 00000000..0cfbebd3
--- /dev/null
+++ b/chart_data_extractor/e2b_charts/charts/__init__.py
@@ -0,0 +1,4 @@
+from .base import ChartType, Chart
+from .bars import BarChart, BoxAndWhiskerChart
+from .pie import PieChart
+from .planar import ScatterChart, LineChart
diff --git a/chart_data_extractor/e2b_charts/charts/bars.py b/chart_data_extractor/e2b_charts/charts/bars.py
new file mode 100644
index 00000000..3d7a9437
--- /dev/null
+++ b/chart_data_extractor/e2b_charts/charts/bars.py
@@ -0,0 +1,140 @@
+from typing import Literal, List
+
+from matplotlib.axes import Axes
+from pydantic import BaseModel, Field
+
+from .base import Chart2D, ChartType
+from ..utils.rounding import dynamic_round
+
+
+class BarData(BaseModel):
+ label: str
+ group: str
+ value: float
+
+
+class BarChart(Chart2D):
+ type: Literal[ChartType.BAR] = ChartType.BAR
+
+ elements: List[BarData] = Field(default_factory=list)
+
+ def _extract_info(self, ax: Axes) -> None:
+ super()._extract_info(ax)
+ for container in ax.containers:
+ group_label = container.get_label()
+ if group_label.startswith("_container"):
+ number = int(group_label[10:])
+ group_label = f"Group {number}"
+
+ heights = [rect.get_height() for rect in container]
+ if all(height == heights[0] for height in heights):
+ # vertical bars
+ self._change_orientation()
+ labels = [label.get_text() for label in ax.get_yticklabels()]
+ values = [rect.get_width() for rect in container]
+ else:
+ # horizontal bars
+ labels = [label.get_text() for label in ax.get_xticklabels()]
+ values = heights
+ for label, value in zip(labels, values):
+ bar = BarData(label=label, value=value, group=group_label)
+ self.elements.append(bar)
+
+
+class BoxAndWhiskerData(BaseModel):
+ label: str
+ min: float
+ first_quartile: float
+ median: float
+ third_quartile: float
+ max: float
+ outliers: List[float]
+
+
+class BoxAndWhiskerChart(Chart2D):
+ type: Literal[ChartType.BOX_AND_WHISKER] = ChartType.BOX_AND_WHISKER
+
+ elements: List[BoxAndWhiskerData] = Field(default_factory=list)
+
+ def _extract_info(self, ax: Axes) -> None:
+ super()._extract_info(ax)
+ labels = [item.get_text() for item in ax.get_xticklabels()]
+
+ boxes = []
+ for label, box in zip(labels, ax.patches):
+ vertices = box.get_path().vertices
+ x_vertices = [dynamic_round(x) for x in vertices[:, 0]]
+ y_vertices = [dynamic_round(y) for y in vertices[:, 1]]
+ x = min(x_vertices)
+ y = min(y_vertices)
+ boxes.append(
+ {
+ "x": x,
+ "y": y,
+ "label": label,
+ "width": max(x_vertices) - x,
+ "height": max(y_vertices) - y,
+ "outliers": [],
+ }
+ )
+
+ orientation = "horizontal"
+ if all(box["height"] == boxes[0]["height"] for box in boxes):
+ orientation = "vertical"
+
+ if orientation == "vertical":
+ self._change_orientation()
+ for box in boxes:
+ box["x"], box["y"] = box["y"], box["x"]
+ box["width"], box["height"] = box["height"], box["width"]
+
+ for i, line in enumerate(ax.lines):
+ xdata = [dynamic_round(x) for x in line.get_xdata()]
+ ydata = [dynamic_round(y) for y in line.get_ydata()]
+
+ if orientation == "vertical":
+ xdata, ydata = ydata, xdata
+
+ if len(xdata) == 1:
+ for box in boxes:
+ if box["x"] <= xdata[0] <= box["x"] + box["width"]:
+ break
+ else:
+ continue
+
+ box["outliers"].append(ydata[0])
+ if len(ydata) != 2:
+ continue
+ for box in boxes:
+ if box["x"] <= xdata[0] <= xdata[1] <= box["x"] + box["width"]:
+ break
+ else:
+ continue
+
+ if (
+ # Check if the line is inside the box, prevent floating point errors
+ ydata[0] == ydata[1]
+ and box["y"] <= ydata[0] <= box["y"] + box["height"]
+ ):
+ box["median"] = ydata[0]
+ continue
+
+ lower_value = min(ydata)
+ upper_value = max(ydata)
+ if upper_value == box["y"]:
+ box["whisker_lower"] = lower_value
+ elif lower_value == box["y"] + box["height"]:
+ box["whisker_upper"] = upper_value
+
+ self.elements = [
+ BoxAndWhiskerData(
+ label=box["label"],
+ min=box["whisker_lower"],
+ first_quartile=box["y"],
+ median=box["median"],
+ third_quartile=box["y"] + box["height"],
+ max=box["whisker_upper"],
+ outliers=box["outliers"],
+ )
+ for box in boxes
+ ]
diff --git a/chart_data_extractor/e2b_charts/charts/base.py b/chart_data_extractor/e2b_charts/charts/base.py
new file mode 100644
index 00000000..0985a9d8
--- /dev/null
+++ b/chart_data_extractor/e2b_charts/charts/base.py
@@ -0,0 +1,75 @@
+import enum
+import re
+from typing import Optional, List, Any
+
+from matplotlib.axes import Axes
+from pydantic import BaseModel, Field
+
+
+class ChartType(str, enum.Enum):
+ LINE = "line"
+ SCATTER = "scatter"
+ BAR = "bar"
+ PIE = "pie"
+ BOX_AND_WHISKER = "box_and_whisker"
+ SUPERCHART = "superchart"
+ UNKNOWN = "unknown"
+
+
+class Chart(BaseModel):
+ type: ChartType
+ title: Optional[str] = None
+
+ elements: List[Any] = Field(default_factory=list)
+
+ def __init__(self, ax: Optional[Axes] = None, **kwargs):
+ super().__init__(**kwargs)
+ if ax:
+ self._extract_info(ax)
+
+ def _extract_info(self, ax: Axes) -> None:
+ """
+ Function to extract information for Chart
+ """
+ title = ax.get_title()
+ if title == "":
+ title = None
+
+ self.title = title
+
+
+class Chart2D(Chart):
+ x_label: Optional[str] = None
+ y_label: Optional[str] = None
+ x_unit: Optional[str] = None
+ y_unit: Optional[str] = None
+
+ def _extract_info(self, ax: Axes) -> None:
+ """
+ Function to extract information for Chart2D
+ """
+ super()._extract_info(ax)
+ x_label = ax.get_xlabel()
+ if x_label == "":
+ x_label = None
+ self.x_label = x_label
+
+ y_label = ax.get_ylabel()
+ if y_label == "":
+ y_label = None
+ self.y_label = y_label
+
+ regex = r"\s\((.*?)\)|\[(.*?)\]"
+ if self.x_label:
+ match = re.search(regex, self.x_label)
+ if match:
+ self.x_unit = match.group(1) or match.group(2)
+
+ if self.y_label:
+ match = re.search(regex, self.y_label)
+ if match:
+ self.y_unit = match.group(1) or match.group(2)
+
+ def _change_orientation(self):
+ self.x_label, self.y_label = self.y_label, self.x_label
+ self.x_unit, self.y_unit = self.y_unit, self.x_unit
diff --git a/chart_data_extractor/e2b_charts/charts/pie.py b/chart_data_extractor/e2b_charts/charts/pie.py
new file mode 100644
index 00000000..2581830b
--- /dev/null
+++ b/chart_data_extractor/e2b_charts/charts/pie.py
@@ -0,0 +1,36 @@
+from decimal import Decimal
+from typing import Literal, List
+
+from matplotlib.axes import Axes
+from pydantic import BaseModel, Field
+
+from .base import Chart, ChartType
+from ..utils.rounding import dynamic_round
+
+
+class PieData(BaseModel):
+ label: str
+ angle: float
+ radius: float
+
+
+class PieChart(Chart):
+ type: Literal[ChartType.PIE] = ChartType.PIE
+
+ elements: List[PieData] = Field(default_factory=list)
+
+ def _extract_info(self, ax: Axes) -> None:
+ super()._extract_info(ax)
+
+ for wedge in ax.patches:
+ pie_data = PieData(
+ label=wedge.get_label(),
+ angle=abs(
+ dynamic_round(
+ Decimal(float(wedge.theta2)) - Decimal(float(wedge.theta1))
+ )
+ ),
+ radius=wedge.r,
+ )
+
+ self.elements.append(pie_data)
diff --git a/chart_data_extractor/e2b_charts/charts/planar.py b/chart_data_extractor/e2b_charts/charts/planar.py
new file mode 100644
index 00000000..bb7d025d
--- /dev/null
+++ b/chart_data_extractor/e2b_charts/charts/planar.py
@@ -0,0 +1,132 @@
+from datetime import date
+from typing import List, Tuple, Union, Sequence, Any, Literal
+
+import matplotlib
+import numpy
+from matplotlib.axes import Axes
+from matplotlib.dates import _SwitchableDateConverter
+from pydantic import BaseModel, field_validator, Field
+
+from .base import Chart2D, ChartType
+from ..utils import is_grid_line
+
+
+class PointData(BaseModel):
+ label: str
+ points: List[Tuple[Union[str, float], Union[str, float]]]
+
+ @field_validator("points", mode="before")
+ @classmethod
+ def transform_points(
+ cls, value
+ ) -> List[Tuple[Union[str, float], Union[str, float]]]:
+ parsed_value = []
+ for x, y in value:
+ x = cls._parse_point(x)
+ y = cls._parse_point(y)
+ parsed_value.append((x, y))
+ return parsed_value
+
+ @staticmethod
+ def _parse_point(point):
+ if isinstance(point, date):
+ return point.isoformat()
+ if isinstance(point, numpy.datetime64):
+ return point.astype("datetime64[s]").astype(str)
+ return point
+
+
+class PointChart(Chart2D):
+ x_ticks: List[Union[str, float]] = Field(default_factory=list)
+ x_tick_labels: List[str] = Field(default_factory=list)
+ x_scale: str = Field(default="linear")
+
+ y_ticks: List[Union[str, float]] = Field(default_factory=list)
+ y_tick_labels: List[str] = Field(default_factory=list)
+ y_scale: str = Field(default="linear")
+
+ elements: List[PointData] = Field(default_factory=list)
+
+ def _extract_info(self, ax: Axes) -> None:
+ """
+ Function to extract information for PointChart
+ """
+ super()._extract_info(ax)
+
+ self.x_tick_labels = [label.get_text() for label in ax.get_xticklabels()]
+
+ x_ticks = ax.get_xticks()
+ self.x_ticks = self._extract_ticks_info(ax.xaxis.converter, x_ticks)
+ self.x_scale = self._detect_scale(
+ ax.xaxis.converter, ax.get_xscale(), self.x_ticks, self.x_tick_labels
+ )
+
+ self.y_tick_labels = [label.get_text() for label in ax.get_yticklabels()]
+ self.y_ticks = self._extract_ticks_info(ax.yaxis.converter, ax.get_yticks())
+ self.y_scale = self._detect_scale(
+ ax.yaxis.converter, ax.get_yscale(), self.y_ticks, self.y_tick_labels
+ )
+
+ @staticmethod
+ def _detect_scale(converter, scale: str, ticks: Sequence, labels: Sequence) -> str:
+ # If the converter is a date converter, it's a datetime scale
+ if isinstance(converter, _SwitchableDateConverter):
+ return "datetime"
+
+ # If the scale is not linear, it can't be categorical
+ if scale != "linear":
+ return scale
+
+ # If all the ticks are integers and are in order from 0 to n-1
+ # and the labels aren't corresponding to the ticks, it's categorical
+ for i, tick_and_label in enumerate(zip(ticks, labels)):
+ tick, label = tick_and_label
+ if isinstance(tick, (int, float)) and tick == i and str(i) != label:
+ continue
+ # Found a tick, which wouldn't be in a categorical scale
+ return "linear"
+
+ return "categorical"
+
+ @staticmethod
+ def _extract_ticks_info(converter: Any, ticks: Sequence) -> list:
+ if isinstance(converter, _SwitchableDateConverter):
+ return [matplotlib.dates.num2date(tick).isoformat() for tick in ticks]
+ else:
+ example_tick = ticks[0]
+
+ if isinstance(example_tick, (int, float)):
+ return [float(tick) for tick in ticks]
+ else:
+ return list(ticks)
+
+
+class LineChart(PointChart):
+ type: Literal[ChartType.LINE] = ChartType.LINE
+
+ def _extract_info(self, ax: Axes) -> None:
+ super()._extract_info(ax)
+
+ for line in ax.get_lines():
+ if is_grid_line(line):
+ continue
+ label = line.get_label()
+ if label.startswith("_child"):
+ number = int(label[6:])
+ label = f"Line {number}"
+
+ points = [(x, y) for x, y in zip(line.get_xdata(), line.get_ydata())]
+ line_data = PointData(label=label, points=points)
+ self.elements.append(line_data)
+
+
+class ScatterChart(PointChart):
+ type: Literal[ChartType.SCATTER] = ChartType.SCATTER
+
+ def _extract_info(self, ax: Axes) -> None:
+ super()._extract_info(ax)
+
+ for collection in ax.collections:
+ points = [(x, y) for x, y in collection.get_offsets()]
+ scatter_data = PointData(label=collection.get_label(), points=points)
+ self.elements.append(scatter_data)
diff --git a/chart_data_extractor/e2b_charts/main.py b/chart_data_extractor/e2b_charts/main.py
new file mode 100644
index 00000000..7f51dbbd
--- /dev/null
+++ b/chart_data_extractor/e2b_charts/main.py
@@ -0,0 +1,119 @@
+from typing import Optional, List, Literal
+
+from matplotlib.axes import Axes
+from matplotlib.collections import PathCollection
+from matplotlib.lines import Line2D
+from matplotlib.patches import Rectangle, Wedge, PathPatch
+from matplotlib.pyplot import Figure
+
+from matplotlib.text import Text
+from pydantic import Field
+
+from .charts import (
+ ChartType,
+ Chart,
+ LineChart,
+ BarChart,
+ BoxAndWhiskerChart,
+ PieChart,
+ ScatterChart,
+)
+from .utils.filtering import is_grid_line
+
+
+class SuperChart(Chart):
+ type: Literal[ChartType.SUPERCHART] = ChartType.SUPERCHART
+ elements: List[
+ LineChart | ScatterChart | BarChart | PieChart | BoxAndWhiskerChart
+ ] = Field(default_factory=list)
+
+ def __init__(self, figure: Figure):
+ title = figure.get_suptitle()
+ super().__init__(title=title)
+
+ self.elements = [get_chart_from_ax(ax) for ax in figure.axes]
+
+
+def _get_type_of_chart(ax: Axes) -> ChartType:
+ objects = list(filter(lambda obj: not isinstance(obj, Text), ax._children))
+
+ # Check for Line plots
+ if all(isinstance(line, Line2D) for line in objects):
+ return ChartType.LINE
+
+ if all(isinstance(box_or_path, (PathPatch, Line2D)) for box_or_path in objects):
+ return ChartType.BOX_AND_WHISKER
+
+ filtered = []
+ for obj in objects:
+ if isinstance(obj, Line2D) and is_grid_line(obj):
+ continue
+ filtered.append(obj)
+
+ objects = filtered
+
+ # Check for Scatter plots
+ if all(isinstance(path, PathCollection) for path in objects):
+ return ChartType.SCATTER
+
+ # Check for Pie plots
+ if all(isinstance(artist, Wedge) for artist in objects):
+ return ChartType.PIE
+
+ # Check for Bar plots
+ if all(isinstance(rect, Rectangle) for rect in objects):
+ return ChartType.BAR
+
+ return ChartType.UNKNOWN
+
+
+def get_chart_from_ax(
+ ax: Axes,
+) -> LineChart | ScatterChart | BarChart | PieChart | BoxAndWhiskerChart | Chart:
+ chart_type = _get_type_of_chart(ax)
+
+ if chart_type == ChartType.LINE:
+ chart = LineChart(ax=ax)
+ elif chart_type == ChartType.SCATTER:
+ chart = ScatterChart(ax=ax)
+ elif chart_type == ChartType.BAR:
+ chart = BarChart(ax=ax)
+ elif chart_type == ChartType.PIE:
+ chart = PieChart(ax=ax)
+ elif chart_type == ChartType.BOX_AND_WHISKER:
+ chart = BoxAndWhiskerChart(ax=ax)
+ else:
+ chart = Chart(ax=ax, type=chart_type)
+
+ return chart
+
+
+def is_figure_blank(axes: List[Axes]) -> bool:
+ """Check if a Matplotlib figure is blank (has no user-added artists)."""
+ for ax in axes:
+ if ax.has_data():
+ return False # The figure contains user-added data
+ return True # No data found, figure is blank
+
+
+def chart_figure_to_chart(figure: Figure) -> Optional[Chart]:
+ """
+ This method is used to extract data from the figure object to a dictionary
+ """
+ # Get all Axes objects from the Figure
+ axes = figure.get_axes()
+
+ if not axes or is_figure_blank(axes):
+ return
+ elif len(axes) > 1:
+ return SuperChart(figure=figure)
+ else:
+ ax = axes[0]
+ return get_chart_from_ax(ax)
+
+
+def chart_figure_to_dict(figure: Figure) -> dict:
+ chart = chart_figure_to_chart(figure)
+ if chart:
+ return chart.model_dump()
+ return {}
diff --git a/chart_data_extractor/e2b_charts/utils/__init__.py b/chart_data_extractor/e2b_charts/utils/__init__.py
new file mode 100644
index 00000000..7822a91f
--- /dev/null
+++ b/chart_data_extractor/e2b_charts/utils/__init__.py
@@ -0,0 +1 @@
+from .filtering import is_grid_line
diff --git a/chart_data_extractor/e2b_charts/utils/filtering.py b/chart_data_extractor/e2b_charts/utils/filtering.py
new file mode 100644
index 00000000..8394c27b
--- /dev/null
+++ b/chart_data_extractor/e2b_charts/utils/filtering.py
@@ -0,0 +1,16 @@
+from matplotlib.lines import Line2D
+
+
+def is_grid_line(line: Line2D) -> bool:
+ x_data = line.get_xdata()
+ if len(x_data) != 2:
+ return False
+
+ y_data = line.get_ydata()
+ if len(y_data) != 2:
+ return False
+
+ if x_data[0] == x_data[1] or y_data[0] == y_data[1]:
+ return True
+
+ return False
diff --git a/chart_data_extractor/e2b_charts/utils/rounding.py b/chart_data_extractor/e2b_charts/utils/rounding.py
new file mode 100644
index 00000000..4efbb667
--- /dev/null
+++ b/chart_data_extractor/e2b_charts/utils/rounding.py
@@ -0,0 +1,13 @@
+from decimal import Decimal, localcontext
+
+
+def dynamic_round(number):
+ # Convert to Decimal for precise control
+ decimal_number = Decimal(str(number))
+
+ # Dynamically determine precision based on magnitude
+ precision = max(1, 8 - decimal_number.adjusted()) # 8 digits of precision
+
+ with localcontext() as ctx:
+ ctx.prec = precision # Set the dynamic precision
+ return +decimal_number # The + operator applies rounding
diff --git a/chart_data_extractor/package.json b/chart_data_extractor/package.json
new file mode 100644
index 00000000..89927490
--- /dev/null
+++ b/chart_data_extractor/package.json
@@ -0,0 +1,18 @@
+{
+ "name": "@e2b/data-extractor",
+ "private": true,
+ "version": "1.0.0",
+ "scripts": {
+ "test": "poetry run pytest -n 4 --verbose -x",
+ "example": "poetry run python3 example.py",
+ "postVersion": "poetry version $(pnpm pkg get version --workspaces=false | tr -d \\\")",
+ "pretest": "poetry install",
+ "lint": "poetry run ruff check .",
+ "format": "poetry run ruff format ."
+ },
+ "devDependencies": {
+ "@typescript-eslint/eslint-plugin": "^7.11.0",
+ "@typescript-eslint/parser": "^7.11.0",
+ "eslint": "^8.57.1"
+ }
+}
diff --git a/chart_data_extractor/poetry.lock b/chart_data_extractor/poetry.lock
new file mode 100644
index 00000000..9ee99afb
--- /dev/null
+++ b/chart_data_extractor/poetry.lock
@@ -0,0 +1,978 @@
+# This file is automatically @generated by Poetry 2.2.1 and should not be changed by hand.
+
+[[package]]
+name = "annotated-types"
+version = "0.7.0"
+description = "Reusable constraint types to use with typing.Annotated"
+optional = false
+python-versions = ">=3.8"
+groups = ["main"]
+files = [
+ {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"},
+ {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"},
+]
+
+[[package]]
+name = "colorama"
+version = "0.4.6"
+description = "Cross-platform colored terminal text."
+optional = false
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
+groups = ["dev"]
+markers = "sys_platform == \"win32\""
+files = [
+ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
+ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
+]
+
+[[package]]
+name = "contourpy"
+version = "1.3.0"
+description = "Python library for calculating contours of 2D quadrilateral grids"
+optional = false
+python-versions = ">=3.9"
+groups = ["main"]
+files = [
+ {file = "contourpy-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:880ea32e5c774634f9fcd46504bf9f080a41ad855f4fef54f5380f5133d343c7"},
+ {file = "contourpy-1.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:76c905ef940a4474a6289c71d53122a4f77766eef23c03cd57016ce19d0f7b42"},
+ {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92f8557cbb07415a4d6fa191f20fd9d2d9eb9c0b61d1b2f52a8926e43c6e9af7"},
+ {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:36f965570cff02b874773c49bfe85562b47030805d7d8360748f3eca570f4cab"},
+ {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cacd81e2d4b6f89c9f8a5b69b86490152ff39afc58a95af002a398273e5ce589"},
+ {file = "contourpy-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69375194457ad0fad3a839b9e29aa0b0ed53bb54db1bfb6c3ae43d111c31ce41"},
+ {file = "contourpy-1.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7a52040312b1a858b5e31ef28c2e865376a386c60c0e248370bbea2d3f3b760d"},
+ {file = "contourpy-1.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3faeb2998e4fcb256542e8a926d08da08977f7f5e62cf733f3c211c2a5586223"},
+ {file = "contourpy-1.3.0-cp310-cp310-win32.whl", hash = "sha256:36e0cff201bcb17a0a8ecc7f454fe078437fa6bda730e695a92f2d9932bd507f"},
+ {file = "contourpy-1.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:87ddffef1dbe5e669b5c2440b643d3fdd8622a348fe1983fad7a0f0ccb1cd67b"},
+ {file = "contourpy-1.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0fa4c02abe6c446ba70d96ece336e621efa4aecae43eaa9b030ae5fb92b309ad"},
+ {file = "contourpy-1.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:834e0cfe17ba12f79963861e0f908556b2cedd52e1f75e6578801febcc6a9f49"},
+ {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dbc4c3217eee163fa3984fd1567632b48d6dfd29216da3ded3d7b844a8014a66"},
+ {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4865cd1d419e0c7a7bf6de1777b185eebdc51470800a9f42b9e9decf17762081"},
+ {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:303c252947ab4b14c08afeb52375b26781ccd6a5ccd81abcdfc1fafd14cf93c1"},
+ {file = "contourpy-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:637f674226be46f6ba372fd29d9523dd977a291f66ab2a74fbeb5530bb3f445d"},
+ {file = "contourpy-1.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:76a896b2f195b57db25d6b44e7e03f221d32fe318d03ede41f8b4d9ba1bff53c"},
+ {file = "contourpy-1.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e1fd23e9d01591bab45546c089ae89d926917a66dceb3abcf01f6105d927e2cb"},
+ {file = "contourpy-1.3.0-cp311-cp311-win32.whl", hash = "sha256:d402880b84df3bec6eab53cd0cf802cae6a2ef9537e70cf75e91618a3801c20c"},
+ {file = "contourpy-1.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:6cb6cc968059db9c62cb35fbf70248f40994dfcd7aa10444bbf8b3faeb7c2d67"},
+ {file = "contourpy-1.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:570ef7cf892f0afbe5b2ee410c507ce12e15a5fa91017a0009f79f7d93a1268f"},
+ {file = "contourpy-1.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:da84c537cb8b97d153e9fb208c221c45605f73147bd4cadd23bdae915042aad6"},
+ {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0be4d8425bfa755e0fd76ee1e019636ccc7c29f77a7c86b4328a9eb6a26d0639"},
+ {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c0da700bf58f6e0b65312d0a5e695179a71d0163957fa381bb3c1f72972537c"},
+ {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb8b141bb00fa977d9122636b16aa67d37fd40a3d8b52dd837e536d64b9a4d06"},
+ {file = "contourpy-1.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3634b5385c6716c258d0419c46d05c8aa7dc8cb70326c9a4fb66b69ad2b52e09"},
+ {file = "contourpy-1.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0dce35502151b6bd35027ac39ba6e5a44be13a68f55735c3612c568cac3805fd"},
+ {file = "contourpy-1.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:aea348f053c645100612b333adc5983d87be69acdc6d77d3169c090d3b01dc35"},
+ {file = "contourpy-1.3.0-cp312-cp312-win32.whl", hash = "sha256:90f73a5116ad1ba7174341ef3ea5c3150ddf20b024b98fb0c3b29034752c8aeb"},
+ {file = "contourpy-1.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:b11b39aea6be6764f84360fce6c82211a9db32a7c7de8fa6dd5397cf1d079c3b"},
+ {file = "contourpy-1.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3e1c7fa44aaae40a2247e2e8e0627f4bea3dd257014764aa644f319a5f8600e3"},
+ {file = "contourpy-1.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:364174c2a76057feef647c802652f00953b575723062560498dc7930fc9b1cb7"},
+ {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32b238b3b3b649e09ce9aaf51f0c261d38644bdfa35cbaf7b263457850957a84"},
+ {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d51fca85f9f7ad0b65b4b9fe800406d0d77017d7270d31ec3fb1cc07358fdea0"},
+ {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:732896af21716b29ab3e988d4ce14bc5133733b85956316fb0c56355f398099b"},
+ {file = "contourpy-1.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d73f659398a0904e125280836ae6f88ba9b178b2fed6884f3b1f95b989d2c8da"},
+ {file = "contourpy-1.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c6c7c2408b7048082932cf4e641fa3b8ca848259212f51c8c59c45aa7ac18f14"},
+ {file = "contourpy-1.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f317576606de89da6b7e0861cf6061f6146ead3528acabff9236458a6ba467f8"},
+ {file = "contourpy-1.3.0-cp313-cp313-win32.whl", hash = "sha256:31cd3a85dbdf1fc002280c65caa7e2b5f65e4a973fcdf70dd2fdcb9868069294"},
+ {file = "contourpy-1.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:4553c421929ec95fb07b3aaca0fae668b2eb5a5203d1217ca7c34c063c53d087"},
+ {file = "contourpy-1.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:345af746d7766821d05d72cb8f3845dfd08dd137101a2cb9b24de277d716def8"},
+ {file = "contourpy-1.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3bb3808858a9dc68f6f03d319acd5f1b8a337e6cdda197f02f4b8ff67ad2057b"},
+ {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:420d39daa61aab1221567b42eecb01112908b2cab7f1b4106a52caaec8d36973"},
+ {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4d63ee447261e963af02642ffcb864e5a2ee4cbfd78080657a9880b8b1868e18"},
+ {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:167d6c890815e1dac9536dca00828b445d5d0df4d6a8c6adb4a7ec3166812fa8"},
+ {file = "contourpy-1.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:710a26b3dc80c0e4febf04555de66f5fd17e9cf7170a7b08000601a10570bda6"},
+ {file = "contourpy-1.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:75ee7cb1a14c617f34a51d11fa7524173e56551646828353c4af859c56b766e2"},
+ {file = "contourpy-1.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:33c92cdae89ec5135d036e7218e69b0bb2851206077251f04a6c4e0e21f03927"},
+ {file = "contourpy-1.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a11077e395f67ffc2c44ec2418cfebed032cd6da3022a94fc227b6faf8e2acb8"},
+ {file = "contourpy-1.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e8134301d7e204c88ed7ab50028ba06c683000040ede1d617298611f9dc6240c"},
+ {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e12968fdfd5bb45ffdf6192a590bd8ddd3ba9e58360b29683c6bb71a7b41edca"},
+ {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fd2a0fc506eccaaa7595b7e1418951f213cf8255be2600f1ea1b61e46a60c55f"},
+ {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4cfb5c62ce023dfc410d6059c936dcf96442ba40814aefbfa575425a3a7f19dc"},
+ {file = "contourpy-1.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68a32389b06b82c2fdd68276148d7b9275b5f5cf13e5417e4252f6d1a34f72a2"},
+ {file = "contourpy-1.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:94e848a6b83da10898cbf1311a815f770acc9b6a3f2d646f330d57eb4e87592e"},
+ {file = "contourpy-1.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d78ab28a03c854a873787a0a42254a0ccb3cb133c672f645c9f9c8f3ae9d0800"},
+ {file = "contourpy-1.3.0-cp39-cp39-win32.whl", hash = "sha256:81cb5ed4952aae6014bc9d0421dec7c5835c9c8c31cdf51910b708f548cf58e5"},
+ {file = "contourpy-1.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:14e262f67bd7e6eb6880bc564dcda30b15e351a594657e55b7eec94b6ef72843"},
+ {file = "contourpy-1.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:fe41b41505a5a33aeaed2a613dccaeaa74e0e3ead6dd6fd3a118fb471644fd6c"},
+ {file = "contourpy-1.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eca7e17a65f72a5133bdbec9ecf22401c62bcf4821361ef7811faee695799779"},
+ {file = "contourpy-1.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1ec4dc6bf570f5b22ed0d7efba0dfa9c5b9e0431aeea7581aa217542d9e809a4"},
+ {file = "contourpy-1.3.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:00ccd0dbaad6d804ab259820fa7cb0b8036bda0686ef844d24125d8287178ce0"},
+ {file = "contourpy-1.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ca947601224119117f7c19c9cdf6b3ab54c5726ef1d906aa4a69dfb6dd58102"},
+ {file = "contourpy-1.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c6ec93afeb848a0845a18989da3beca3eec2c0f852322efe21af1931147d12cb"},
+ {file = "contourpy-1.3.0.tar.gz", hash = "sha256:7ffa0db17717a8ffb127efd0c95a4362d996b892c2904db72428d5b52e1938a4"},
+]
+
+[package.dependencies]
+numpy = ">=1.23"
+
+[package.extras]
+bokeh = ["bokeh", "selenium"]
+docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"]
+mypy = ["contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.11.1)", "types-Pillow"]
+test = ["Pillow", "contourpy[test-no-images]", "matplotlib"]
+test-no-images = ["pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist", "wurlitzer"]
+
+[[package]]
+name = "cycler"
+version = "0.12.1"
+description = "Composable style cycles"
+optional = false
+python-versions = ">=3.8"
+groups = ["main"]
+files = [
+ {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"},
+ {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"},
+]
+
+[package.extras]
+docs = ["ipython", "matplotlib", "numpydoc", "sphinx"]
+tests = ["pytest", "pytest-cov", "pytest-xdist"]
+
+[[package]]
+name = "exceptiongroup"
+version = "1.3.1"
+description = "Backport of PEP 654 (exception groups)"
+optional = false
+python-versions = ">=3.7"
+groups = ["dev"]
+markers = "python_version == \"3.10\""
+files = [
+ {file = "exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598"},
+ {file = "exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219"},
+]
+
+[package.dependencies]
+typing-extensions = {version = ">=4.6.0", markers = "python_version < \"3.13\""}
+
+[package.extras]
+test = ["pytest (>=6)"]
+
+[[package]]
+name = "fonttools"
+version = "4.61.0"
+description = "Tools to manipulate font files"
+optional = false
+python-versions = ">=3.10"
+groups = ["main"]
+files = [
+ {file = "fonttools-4.61.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:dc25a4a9c1225653e4431a9413d0381b1c62317b0f543bdcec24e1991f612f33"},
+ {file = "fonttools-4.61.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b493c32d2555e9944ec1b911ea649ff8f01a649ad9cba6c118d6798e932b3f0"},
+ {file = "fonttools-4.61.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ad751319dc532a79bdf628b8439af167181b4210a0cd28a8935ca615d9fdd727"},
+ {file = "fonttools-4.61.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2de14557d113faa5fb519f7f29c3abe4d69c17fe6a5a2595cc8cda7338029219"},
+ {file = "fonttools-4.61.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:59587bbe455dbdf75354a9dbca1697a35a8903e01fab4248d6b98a17032cee52"},
+ {file = "fonttools-4.61.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:46cb3d9279f758ac0cf671dc3482da877104b65682679f01b246515db03dbb72"},
+ {file = "fonttools-4.61.0-cp310-cp310-win32.whl", hash = "sha256:58b4f1b78dfbfe855bb8a6801b31b8cdcca0e2847ec769ad8e0b0b692832dd3b"},
+ {file = "fonttools-4.61.0-cp310-cp310-win_amd64.whl", hash = "sha256:68704a8bbe0b61976262b255e90cde593dc0fe3676542d9b4d846bad2a890a76"},
+ {file = "fonttools-4.61.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a32a16951cbf113d38f1dd8551b277b6e06e0f6f776fece0f99f746d739e1be3"},
+ {file = "fonttools-4.61.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:328a9c227984bebaf69f3ac9062265f8f6acc7ddf2e4e344c63358579af0aa3d"},
+ {file = "fonttools-4.61.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2f0bafc8a3b3749c69cc610e5aa3da832d39c2a37a68f03d18ec9a02ecaac04a"},
+ {file = "fonttools-4.61.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b5ca59b7417d149cf24e4c1933c9f44b2957424fc03536f132346d5242e0ebe5"},
+ {file = "fonttools-4.61.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:df8cbce85cf482eb01f4551edca978c719f099c623277bda8332e5dbe7dba09d"},
+ {file = "fonttools-4.61.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7fb5b84f48a6a733ca3d7f41aa9551908ccabe8669ffe79586560abcc00a9cfd"},
+ {file = "fonttools-4.61.0-cp311-cp311-win32.whl", hash = "sha256:787ef9dfd1ea9fe49573c272412ae5f479d78e671981819538143bec65863865"},
+ {file = "fonttools-4.61.0-cp311-cp311-win_amd64.whl", hash = "sha256:14fafda386377b6131d9e448af42d0926bad47e038de0e5ba1d58c25d621f028"},
+ {file = "fonttools-4.61.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e24a1565c4e57111ec7f4915f8981ecbb61adf66a55f378fdc00e206059fcfef"},
+ {file = "fonttools-4.61.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e2bfacb5351303cae9f072ccf3fc6ecb437a6f359c0606bae4b1ab6715201d87"},
+ {file = "fonttools-4.61.0-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0bdcf2e29d65c26299cc3d502f4612365e8b90a939f46cd92d037b6cb7bb544a"},
+ {file = "fonttools-4.61.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e6cd0d9051b8ddaf7385f99dd82ec2a058e2b46cf1f1961e68e1ff20fcbb61af"},
+ {file = "fonttools-4.61.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e074bc07c31406f45c418e17c1722e83560f181d122c412fa9e815df0ff74810"},
+ {file = "fonttools-4.61.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5a9b78da5d5faa17e63b2404b77feeae105c1b7e75f26020ab7a27b76e02039f"},
+ {file = "fonttools-4.61.0-cp312-cp312-win32.whl", hash = "sha256:9821ed77bb676736b88fa87a737c97b6af06e8109667e625a4f00158540ce044"},
+ {file = "fonttools-4.61.0-cp312-cp312-win_amd64.whl", hash = "sha256:0011d640afa61053bc6590f9a3394bd222de7cfde19346588beabac374e9d8ac"},
+ {file = "fonttools-4.61.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba774b8cbd8754f54b8eb58124e8bd45f736b2743325ab1a5229698942b9b433"},
+ {file = "fonttools-4.61.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c84b430616ed73ce46e9cafd0bf0800e366a3e02fb7e1ad7c1e214dbe3862b1f"},
+ {file = "fonttools-4.61.0-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b2b734d8391afe3c682320840c8191de9bd24e7eb85768dd4dc06ed1b63dbb1b"},
+ {file = "fonttools-4.61.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a5c5fff72bf31b0e558ed085e4fd7ed96eb85881404ecc39ed2a779e7cf724eb"},
+ {file = "fonttools-4.61.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:14a290c5c93fcab76b7f451e6a4b7721b712d90b3b5ed6908f1abcf794e90d6d"},
+ {file = "fonttools-4.61.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:13e3e20a5463bfeb77b3557d04b30bd6a96a6bb5c15c7b2e7908903e69d437a0"},
+ {file = "fonttools-4.61.0-cp313-cp313-win32.whl", hash = "sha256:6781e7a4bb010be1cd69a29927b0305c86b843395f2613bdabe115f7d6ea7f34"},
+ {file = "fonttools-4.61.0-cp313-cp313-win_amd64.whl", hash = "sha256:c53b47834ae41e8e4829171cc44fec0fdf125545a15f6da41776b926b9645a9a"},
+ {file = "fonttools-4.61.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:96dfc9bc1f2302224e48e6ee37e656eddbab810b724b52e9d9c13a57a6abad01"},
+ {file = "fonttools-4.61.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:3b2065d94e5d63aafc2591c8b6ccbdb511001d9619f1bca8ad39b745ebeb5efa"},
+ {file = "fonttools-4.61.0-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e0d87e81e4d869549585ba0beb3f033718501c1095004f5e6aef598d13ebc216"},
+ {file = "fonttools-4.61.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1cfa2eb9bae650e58f0e8ad53c49d19a844d6034d6b259f30f197238abc1ccee"},
+ {file = "fonttools-4.61.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4238120002e68296d55e091411c09eab94e111c8ce64716d17df53fd0eb3bb3d"},
+ {file = "fonttools-4.61.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b6ceac262cc62bec01b3bb59abccf41b24ef6580869e306a4e88b7e56bb4bdda"},
+ {file = "fonttools-4.61.0-cp314-cp314-win32.whl", hash = "sha256:adbb4ecee1a779469a77377bbe490565effe8fce6fb2e6f95f064de58f8bac85"},
+ {file = "fonttools-4.61.0-cp314-cp314-win_amd64.whl", hash = "sha256:02bdf8e04d1a70476564b8640380f04bb4ac74edc1fc71f1bacb840b3e398ee9"},
+ {file = "fonttools-4.61.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:627216062d90ab0d98215176d8b9562c4dd5b61271d35f130bcd30f6a8aaa33a"},
+ {file = "fonttools-4.61.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7b446623c9cd5f14a59493818eaa80255eec2468c27d2c01b56e05357c263195"},
+ {file = "fonttools-4.61.0-cp314-cp314t-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:70e2a0c0182ee75e493ef33061bfebf140ea57e035481d2f95aa03b66c7a0e05"},
+ {file = "fonttools-4.61.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9064b0f55b947e929ac669af5311ab1f26f750214db6dd9a0c97e091e918f486"},
+ {file = "fonttools-4.61.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2cb5e45a824ce14b90510024d0d39dae51bd4fbb54c42a9334ea8c8cf4d95cbe"},
+ {file = "fonttools-4.61.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6e5ca8c62efdec7972dfdfd454415c4db49b89aeaefaaacada432f3b7eea9866"},
+ {file = "fonttools-4.61.0-cp314-cp314t-win32.whl", hash = "sha256:63c7125d31abe3e61d7bb917329b5543c5b3448db95f24081a13aaf064360fc8"},
+ {file = "fonttools-4.61.0-cp314-cp314t-win_amd64.whl", hash = "sha256:67d841aa272be5500de7f447c40d1d8452783af33b4c3599899319f6ef9ad3c1"},
+ {file = "fonttools-4.61.0-py3-none-any.whl", hash = "sha256:276f14c560e6f98d24ef7f5f44438e55ff5a67f78fa85236b218462c9f5d0635"},
+ {file = "fonttools-4.61.0.tar.gz", hash = "sha256:ec520a1f0c7758d7a858a00f090c1745f6cde6a7c5e76fb70ea4044a15f712e7"},
+]
+
+[package.extras]
+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.45.0)"]
+symfont = ["sympy"]
+type1 = ["xattr ; sys_platform == \"darwin\""]
+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 = "iniconfig"
+version = "2.0.0"
+description = "brain-dead simple config-ini parsing"
+optional = false
+python-versions = ">=3.7"
+groups = ["dev"]
+files = [
+ {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"},
+ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
+]
+
+[[package]]
+name = "kiwisolver"
+version = "1.4.7"
+description = "A fast implementation of the Cassowary constraint solver"
+optional = false
+python-versions = ">=3.8"
+groups = ["main"]
+files = [
+ {file = "kiwisolver-1.4.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8a9c83f75223d5e48b0bc9cb1bf2776cf01563e00ade8775ffe13b0b6e1af3a6"},
+ {file = "kiwisolver-1.4.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:58370b1ffbd35407444d57057b57da5d6549d2d854fa30249771775c63b5fe17"},
+ {file = "kiwisolver-1.4.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aa0abdf853e09aff551db11fce173e2177d00786c688203f52c87ad7fcd91ef9"},
+ {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8d53103597a252fb3ab8b5845af04c7a26d5e7ea8122303dd7a021176a87e8b9"},
+ {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:88f17c5ffa8e9462fb79f62746428dd57b46eb931698e42e990ad63103f35e6c"},
+ {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88a9ca9c710d598fd75ee5de59d5bda2684d9db36a9f50b6125eaea3969c2599"},
+ {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f4d742cb7af1c28303a51b7a27aaee540e71bb8e24f68c736f6f2ffc82f2bf05"},
+ {file = "kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e28c7fea2196bf4c2f8d46a0415c77a1c480cc0724722f23d7410ffe9842c407"},
+ {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e968b84db54f9d42046cf154e02911e39c0435c9801681e3fc9ce8a3c4130278"},
+ {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0c18ec74c0472de033e1bebb2911c3c310eef5649133dd0bedf2a169a1b269e5"},
+ {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8f0ea6da6d393d8b2e187e6a5e3fb81f5862010a40c3945e2c6d12ae45cfb2ad"},
+ {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:f106407dda69ae456dd1227966bf445b157ccc80ba0dff3802bb63f30b74e895"},
+ {file = "kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:84ec80df401cfee1457063732d90022f93951944b5b58975d34ab56bb150dfb3"},
+ {file = "kiwisolver-1.4.7-cp310-cp310-win32.whl", hash = "sha256:71bb308552200fb2c195e35ef05de12f0c878c07fc91c270eb3d6e41698c3bcc"},
+ {file = "kiwisolver-1.4.7-cp310-cp310-win_amd64.whl", hash = "sha256:44756f9fd339de0fb6ee4f8c1696cfd19b2422e0d70b4cefc1cc7f1f64045a8c"},
+ {file = "kiwisolver-1.4.7-cp310-cp310-win_arm64.whl", hash = "sha256:78a42513018c41c2ffd262eb676442315cbfe3c44eed82385c2ed043bc63210a"},
+ {file = "kiwisolver-1.4.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d2b0e12a42fb4e72d509fc994713d099cbb15ebf1103545e8a45f14da2dfca54"},
+ {file = "kiwisolver-1.4.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2a8781ac3edc42ea4b90bc23e7d37b665d89423818e26eb6df90698aa2287c95"},
+ {file = "kiwisolver-1.4.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:46707a10836894b559e04b0fd143e343945c97fd170d69a2d26d640b4e297935"},
+ {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef97b8df011141c9b0f6caf23b29379f87dd13183c978a30a3c546d2c47314cb"},
+ {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab58c12a2cd0fc769089e6d38466c46d7f76aced0a1f54c77652446733d2d02"},
+ {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:803b8e1459341c1bb56d1c5c010406d5edec8a0713a0945851290a7930679b51"},
+ {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f9a9e8a507420fe35992ee9ecb302dab68550dedc0da9e2880dd88071c5fb052"},
+ {file = "kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18077b53dc3bb490e330669a99920c5e6a496889ae8c63b58fbc57c3d7f33a18"},
+ {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6af936f79086a89b3680a280c47ea90b4df7047b5bdf3aa5c524bbedddb9e545"},
+ {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:3abc5b19d24af4b77d1598a585b8a719beb8569a71568b66f4ebe1fb0449460b"},
+ {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:933d4de052939d90afbe6e9d5273ae05fb836cc86c15b686edd4b3560cc0ee36"},
+ {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:65e720d2ab2b53f1f72fb5da5fb477455905ce2c88aaa671ff0a447c2c80e8e3"},
+ {file = "kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3bf1ed55088f214ba6427484c59553123fdd9b218a42bbc8c6496d6754b1e523"},
+ {file = "kiwisolver-1.4.7-cp311-cp311-win32.whl", hash = "sha256:4c00336b9dd5ad96d0a558fd18a8b6f711b7449acce4c157e7343ba92dd0cf3d"},
+ {file = "kiwisolver-1.4.7-cp311-cp311-win_amd64.whl", hash = "sha256:929e294c1ac1e9f615c62a4e4313ca1823ba37326c164ec720a803287c4c499b"},
+ {file = "kiwisolver-1.4.7-cp311-cp311-win_arm64.whl", hash = "sha256:e33e8fbd440c917106b237ef1a2f1449dfbb9b6f6e1ce17c94cd6a1e0d438376"},
+ {file = "kiwisolver-1.4.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:5360cc32706dab3931f738d3079652d20982511f7c0ac5711483e6eab08efff2"},
+ {file = "kiwisolver-1.4.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:942216596dc64ddb25adb215c3c783215b23626f8d84e8eff8d6d45c3f29f75a"},
+ {file = "kiwisolver-1.4.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:48b571ecd8bae15702e4f22d3ff6a0f13e54d3d00cd25216d5e7f658242065ee"},
+ {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ad42ba922c67c5f219097b28fae965e10045ddf145d2928bfac2eb2e17673640"},
+ {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:612a10bdae23404a72941a0fc8fa2660c6ea1217c4ce0dbcab8a8f6543ea9e7f"},
+ {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9e838bba3a3bac0fe06d849d29772eb1afb9745a59710762e4ba3f4cb8424483"},
+ {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:22f499f6157236c19f4bbbd472fa55b063db77a16cd74d49afe28992dff8c258"},
+ {file = "kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693902d433cf585133699972b6d7c42a8b9f8f826ebcaf0132ff55200afc599e"},
+ {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4e77f2126c3e0b0d055f44513ed349038ac180371ed9b52fe96a32aa071a5107"},
+ {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:657a05857bda581c3656bfc3b20e353c232e9193eb167766ad2dc58b56504948"},
+ {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4bfa75a048c056a411f9705856abfc872558e33c055d80af6a380e3658766038"},
+ {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:34ea1de54beef1c104422d210c47c7d2a4999bdecf42c7b5718fbe59a4cac383"},
+ {file = "kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:90da3b5f694b85231cf93586dad5e90e2d71b9428f9aad96952c99055582f520"},
+ {file = "kiwisolver-1.4.7-cp312-cp312-win32.whl", hash = "sha256:18e0cca3e008e17fe9b164b55735a325140a5a35faad8de92dd80265cd5eb80b"},
+ {file = "kiwisolver-1.4.7-cp312-cp312-win_amd64.whl", hash = "sha256:58cb20602b18f86f83a5c87d3ee1c766a79c0d452f8def86d925e6c60fbf7bfb"},
+ {file = "kiwisolver-1.4.7-cp312-cp312-win_arm64.whl", hash = "sha256:f5a8b53bdc0b3961f8b6125e198617c40aeed638b387913bf1ce78afb1b0be2a"},
+ {file = "kiwisolver-1.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2e6039dcbe79a8e0f044f1c39db1986a1b8071051efba3ee4d74f5b365f5226e"},
+ {file = "kiwisolver-1.4.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a1ecf0ac1c518487d9d23b1cd7139a6a65bc460cd101ab01f1be82ecf09794b6"},
+ {file = "kiwisolver-1.4.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7ab9ccab2b5bd5702ab0803676a580fffa2aa178c2badc5557a84cc943fcf750"},
+ {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f816dd2277f8d63d79f9c8473a79fe54047bc0467754962840782c575522224d"},
+ {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf8bcc23ceb5a1b624572a1623b9f79d2c3b337c8c455405ef231933a10da379"},
+ {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dea0bf229319828467d7fca8c7c189780aa9ff679c94539eed7532ebe33ed37c"},
+ {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c06a4c7cf15ec739ce0e5971b26c93638730090add60e183530d70848ebdd34"},
+ {file = "kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:913983ad2deb14e66d83c28b632fd35ba2b825031f2fa4ca29675e665dfecbe1"},
+ {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5337ec7809bcd0f424c6b705ecf97941c46279cf5ed92311782c7c9c2026f07f"},
+ {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4c26ed10c4f6fa6ddb329a5120ba3b6db349ca192ae211e882970bfc9d91420b"},
+ {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c619b101e6de2222c1fcb0531e1b17bbffbe54294bfba43ea0d411d428618c27"},
+ {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:073a36c8273647592ea332e816e75ef8da5c303236ec0167196793eb1e34657a"},
+ {file = "kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3ce6b2b0231bda412463e152fc18335ba32faf4e8c23a754ad50ffa70e4091ee"},
+ {file = "kiwisolver-1.4.7-cp313-cp313-win32.whl", hash = "sha256:f4c9aee212bc89d4e13f58be11a56cc8036cabad119259d12ace14b34476fd07"},
+ {file = "kiwisolver-1.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:8a3ec5aa8e38fc4c8af308917ce12c536f1c88452ce554027e55b22cbbfbff76"},
+ {file = "kiwisolver-1.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:76c8094ac20ec259471ac53e774623eb62e6e1f56cd8690c67ce6ce4fcb05650"},
+ {file = "kiwisolver-1.4.7-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5d5abf8f8ec1f4e22882273c423e16cae834c36856cac348cfbfa68e01c40f3a"},
+ {file = "kiwisolver-1.4.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:aeb3531b196ef6f11776c21674dba836aeea9d5bd1cf630f869e3d90b16cfade"},
+ {file = "kiwisolver-1.4.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b7d755065e4e866a8086c9bdada157133ff466476a2ad7861828e17b6026e22c"},
+ {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08471d4d86cbaec61f86b217dd938a83d85e03785f51121e791a6e6689a3be95"},
+ {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7bbfcb7165ce3d54a3dfbe731e470f65739c4c1f85bb1018ee912bae139e263b"},
+ {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d34eb8494bea691a1a450141ebb5385e4b69d38bb8403b5146ad279f4b30fa3"},
+ {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9242795d174daa40105c1d86aba618e8eab7bf96ba8c3ee614da8302a9f95503"},
+ {file = "kiwisolver-1.4.7-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a0f64a48bb81af7450e641e3fe0b0394d7381e342805479178b3d335d60ca7cf"},
+ {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8e045731a5416357638d1700927529e2b8ab304811671f665b225f8bf8d8f933"},
+ {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:4322872d5772cae7369f8351da1edf255a604ea7087fe295411397d0cfd9655e"},
+ {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:e1631290ee9271dffe3062d2634c3ecac02c83890ada077d225e081aca8aab89"},
+ {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:edcfc407e4eb17e037bca59be0e85a2031a2ac87e4fed26d3e9df88b4165f92d"},
+ {file = "kiwisolver-1.4.7-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:4d05d81ecb47d11e7f8932bd8b61b720bf0b41199358f3f5e36d38e28f0532c5"},
+ {file = "kiwisolver-1.4.7-cp38-cp38-win32.whl", hash = "sha256:b38ac83d5f04b15e515fd86f312479d950d05ce2368d5413d46c088dda7de90a"},
+ {file = "kiwisolver-1.4.7-cp38-cp38-win_amd64.whl", hash = "sha256:d83db7cde68459fc803052a55ace60bea2bae361fc3b7a6d5da07e11954e4b09"},
+ {file = "kiwisolver-1.4.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3f9362ecfca44c863569d3d3c033dbe8ba452ff8eed6f6b5806382741a1334bd"},
+ {file = "kiwisolver-1.4.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e8df2eb9b2bac43ef8b082e06f750350fbbaf2887534a5be97f6cf07b19d9583"},
+ {file = "kiwisolver-1.4.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f32d6edbc638cde7652bd690c3e728b25332acbadd7cad670cc4a02558d9c417"},
+ {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e2e6c39bd7b9372b0be21456caab138e8e69cc0fc1190a9dfa92bd45a1e6e904"},
+ {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dda56c24d869b1193fcc763f1284b9126550eaf84b88bbc7256e15028f19188a"},
+ {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79849239c39b5e1fd906556c474d9b0439ea6792b637511f3fe3a41158d89ca8"},
+ {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5e3bc157fed2a4c02ec468de4ecd12a6e22818d4f09cde2c31ee3226ffbefab2"},
+ {file = "kiwisolver-1.4.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3da53da805b71e41053dc670f9a820d1157aae77b6b944e08024d17bcd51ef88"},
+ {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8705f17dfeb43139a692298cb6637ee2e59c0194538153e83e9ee0c75c2eddde"},
+ {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:82a5c2f4b87c26bb1a0ef3d16b5c4753434633b83d365cc0ddf2770c93829e3c"},
+ {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ce8be0466f4c0d585cdb6c1e2ed07232221df101a4c6f28821d2aa754ca2d9e2"},
+ {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:409afdfe1e2e90e6ee7fc896f3df9a7fec8e793e58bfa0d052c8a82f99c37abb"},
+ {file = "kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5b9c3f4ee0b9a439d2415012bd1b1cc2df59e4d6a9939f4d669241d30b414327"},
+ {file = "kiwisolver-1.4.7-cp39-cp39-win32.whl", hash = "sha256:a79ae34384df2b615eefca647a2873842ac3b596418032bef9a7283675962644"},
+ {file = "kiwisolver-1.4.7-cp39-cp39-win_amd64.whl", hash = "sha256:cf0438b42121a66a3a667de17e779330fc0f20b0d97d59d2f2121e182b0505e4"},
+ {file = "kiwisolver-1.4.7-cp39-cp39-win_arm64.whl", hash = "sha256:764202cc7e70f767dab49e8df52c7455e8de0df5d858fa801a11aa0d882ccf3f"},
+ {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:94252291e3fe68001b1dd747b4c0b3be12582839b95ad4d1b641924d68fd4643"},
+ {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5b7dfa3b546da08a9f622bb6becdb14b3e24aaa30adba66749d38f3cc7ea9706"},
+ {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd3de6481f4ed8b734da5df134cd5a6a64fe32124fe83dde1e5b5f29fe30b1e6"},
+ {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a91b5f9f1205845d488c928e8570dcb62b893372f63b8b6e98b863ebd2368ff2"},
+ {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40fa14dbd66b8b8f470d5fc79c089a66185619d31645f9b0773b88b19f7223c4"},
+ {file = "kiwisolver-1.4.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:eb542fe7933aa09d8d8f9d9097ef37532a7df6497819d16efe4359890a2f417a"},
+ {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bfa1acfa0c54932d5607e19a2c24646fb4c1ae2694437789129cf099789a3b00"},
+ {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:eee3ea935c3d227d49b4eb85660ff631556841f6e567f0f7bda972df6c2c9935"},
+ {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f3160309af4396e0ed04db259c3ccbfdc3621b5559b5453075e5de555e1f3a1b"},
+ {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a17f6a29cf8935e587cc8a4dbfc8368c55edc645283db0ce9801016f83526c2d"},
+ {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:10849fb2c1ecbfae45a693c070e0320a91b35dd4bcf58172c023b994283a124d"},
+ {file = "kiwisolver-1.4.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:ac542bf38a8a4be2dc6b15248d36315ccc65f0743f7b1a76688ffb6b5129a5c2"},
+ {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:8b01aac285f91ca889c800042c35ad3b239e704b150cfd3382adfc9dcc780e39"},
+ {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:48be928f59a1f5c8207154f935334d374e79f2b5d212826307d072595ad76a2e"},
+ {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f37cfe618a117e50d8c240555331160d73d0411422b59b5ee217843d7b693608"},
+ {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:599b5c873c63a1f6ed7eead644a8a380cfbdf5db91dcb6f85707aaab213b1674"},
+ {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:801fa7802e5cfabe3ab0c81a34c323a319b097dfb5004be950482d882f3d7225"},
+ {file = "kiwisolver-1.4.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:0c6c43471bc764fad4bc99c5c2d6d16a676b1abf844ca7c8702bdae92df01ee0"},
+ {file = "kiwisolver-1.4.7.tar.gz", hash = "sha256:9893ff81bd7107f7b685d3017cc6583daadb4fc26e4a888350df530e41980a60"},
+]
+
+[[package]]
+name = "matplotlib"
+version = "3.10.9"
+description = "Python plotting package"
+optional = false
+python-versions = ">=3.10"
+groups = ["main"]
+files = [
+ {file = "matplotlib-3.10.9-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:77210dce9cb8153dffc967efaae990543392563d5a376d4dd8539bebcb0ed217"},
+ {file = "matplotlib-3.10.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1e7698ac9868428e84d2c967424803b2472ff7167d9d6590d4204ed775343c3b"},
+ {file = "matplotlib-3.10.9-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1aa972116abb4c9d201bf245620b433726cb6856f3bef6a78f776a00f5c92d37"},
+ {file = "matplotlib-3.10.9-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ae2f11957b27ce53497dd4d7b235c4d4f1faf383dfb39d0c5beb833bff883294"},
+ {file = "matplotlib-3.10.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b049278ddce116aaa1c1377ebf58adea909132dfce0281cf7e3a1ea9fc2e2c65"},
+ {file = "matplotlib-3.10.9-cp310-cp310-win_amd64.whl", hash = "sha256:82834c3c292d24d3a8aae77cd2d20019de69d692a34a970e4fdb8d33e2ea3dda"},
+ {file = "matplotlib-3.10.9-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:68cfdcede415f7c8f5577b03303dd94526cdb6d11036cecdc205e08733b2d2bb"},
+ {file = "matplotlib-3.10.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfca0129678bd56379db26c52b5d77ed7de314c047492fbdc763aa7501710cfb"},
+ {file = "matplotlib-3.10.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8e436d155fa8a3399dc62683f8f5d0e2e50d25d0144a73edd73f82eec8f4abfb"},
+ {file = "matplotlib-3.10.9-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:56fc0bd271b00025c6edfdc7c2dcd247372c8e1544971d62e1dc7c17367e8bf9"},
+ {file = "matplotlib-3.10.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a5a6104ed666402ba5106d7f36e0e0cdca4e8d7fa4d39708ca88019e2835a2eb"},
+ {file = "matplotlib-3.10.9-cp311-cp311-win_amd64.whl", hash = "sha256:d730e984eddf56974c3e72b6129c7ca462ac38dc624338f4b0b23eb23ecba00f"},
+ {file = "matplotlib-3.10.9-cp311-cp311-win_arm64.whl", hash = "sha256:51bf0ddbdc598e060d46c16b5590708f81a1624cefbaaf62f6a81bf9285b8c80"},
+ {file = "matplotlib-3.10.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f0c3c28d9fbcc1fe7a03be236d73430cf6409c41fb2383a7ac52fe932b072cb1"},
+ {file = "matplotlib-3.10.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:41cb28c2bd769aa3e98322c6ab09854cbcc52ab69d2759d681bba3e327b2b320"},
+ {file = "matplotlib-3.10.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ae20801130378b82d647ff5047c07316295b68dc054ca6b3c13519d0ea624285"},
+ {file = "matplotlib-3.10.9-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6c63ebcd8b4b169eb2f5c200552ae6b8be8999a005b6b507ed76fb8d7d674fe2"},
+ {file = "matplotlib-3.10.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d75d11c949914165976c621b2324f9ef162af7ebf4b057ddf95dd1dba7e5edcf"},
+ {file = "matplotlib-3.10.9-cp312-cp312-win_amd64.whl", hash = "sha256:d091f9d758b34aaaaa6331d13574bf01891d903b3dec59bfff458ef7551de5d6"},
+ {file = "matplotlib-3.10.9-cp312-cp312-win_arm64.whl", hash = "sha256:10cc5ce06d10231c36f40e875f3c7e8050362a4ee8f0ee5d29a6b3277d57bb42"},
+ {file = "matplotlib-3.10.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b580440f1ff81a0e34122051a3dfabb7e4b7f9e380629929bde0eff9af72165f"},
+ {file = "matplotlib-3.10.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b1b745c489cd1a77a0dc1120a05dc87af9798faebc913601feb8c73d89bf2d1e"},
+ {file = "matplotlib-3.10.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8f3bcac1ca5ed000a6f4337d47ba67dfddf37ed6a46c15fd7f014997f7bf865f"},
+ {file = "matplotlib-3.10.9-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7a8d66a55def891c33147ba3ba9bfcabf0b526a43764c818acbb4525e5ed0838"},
+ {file = "matplotlib-3.10.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d843374407c4017a6403b59c6c81606773d136f3259d5b6da3131bc814542cc2"},
+ {file = "matplotlib-3.10.9-cp313-cp313-win_amd64.whl", hash = "sha256:f4399f64b3e94cd500195490972ae1ee81170df1636fa15364d157d5bdd7b921"},
+ {file = "matplotlib-3.10.9-cp313-cp313-win_arm64.whl", hash = "sha256:ba7b3b8ef09eab7df0e86e9ae086faa433efbfbdb46afcb3aa16aabf779469a8"},
+ {file = "matplotlib-3.10.9-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:09218df8a93712bd6ea133e83a153c755448cf7868316c531cffcc43f69d1cc9"},
+ {file = "matplotlib-3.10.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:82368699727bfb7b0182e1aa13082e3c08e092fa1a25d3e1fd92405bff96f6d4"},
+ {file = "matplotlib-3.10.9-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3225f4e1edcb8c86c884ddf79ebe20ecd0a67d30188f279897554ccd8fded4dc"},
+ {file = "matplotlib-3.10.9-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:de2445a0c6690d21b7eb6ce071cebad6d40a2e9bdf10d039074a96ba19797b99"},
+ {file = "matplotlib-3.10.9-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:b2b9516251cb89ff618d757daec0e2ed1bf21248013844a853d87ef85ab3081d"},
+ {file = "matplotlib-3.10.9-cp313-cp313t-win_amd64.whl", hash = "sha256:e9fae004b941b23ff2edcf1567a857ed77bafc8086ffa258190462328434faf8"},
+ {file = "matplotlib-3.10.9-cp313-cp313t-win_arm64.whl", hash = "sha256:6b63d9c7c769b88ab81e10dc86e4e0607cf56817b9f9e6cf24b2a5f1693b8e38"},
+ {file = "matplotlib-3.10.9-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:172db52c9e683f5d12eaf57f0f54834190e12581fe1cc2a19595a8f5acb4e77d"},
+ {file = "matplotlib-3.10.9-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:97e35e8d39ccc85859095e01a53847432ba9a53ddf7986f7a54a11b73d0e143f"},
+ {file = "matplotlib-3.10.9-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aba1615dabe83188e19d4f75a253c6a08423e04c1425e64039f800050a69de6b"},
+ {file = "matplotlib-3.10.9-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34cf8167e023ad956c15f36302911d5406bd99a9862c1a8499ea6f7c0e015dc2"},
+ {file = "matplotlib-3.10.9-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:59476c6d29d612b8e9bb6ce8c5b631be6ba8f9e3a2421f22a02b192c7dd28716"},
+ {file = "matplotlib-3.10.9-cp314-cp314-win_amd64.whl", hash = "sha256:336b9acc64d309063126edcdaca00db9373af3c476bb94388fe9c5a53ad13e6f"},
+ {file = "matplotlib-3.10.9-cp314-cp314-win_arm64.whl", hash = "sha256:2dc9477819ffd78ad12a20df1d9d6a6bd4fec6aaa9072681465fddca052f1456"},
+ {file = "matplotlib-3.10.9-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:da4e09638420548f31c354032a6250e473c68e5a4e96899b4844cf39ddea23fe"},
+ {file = "matplotlib-3.10.9-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:345f6f68ecc8da0ca56fad2ea08fde1a115eda530079eca185d50a7bc3e146c6"},
+ {file = "matplotlib-3.10.9-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4edcfbd8565339aa62f1cd4012f7180926fdbe71850f7b0d3c379c175cd6b66c"},
+ {file = "matplotlib-3.10.9-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6be157fe17fc37cb95ac1d7374cf717ce9259616edec911a78d9d26dae8522d4"},
+ {file = "matplotlib-3.10.9-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:4e42042d54db34fda4e95a7bd3e5789c2a995d2dad3eb8850232ee534092fbbf"},
+ {file = "matplotlib-3.10.9-cp314-cp314t-win_amd64.whl", hash = "sha256:c27df8b3848f32a83d1767566595e43cfaa4460380974da06f4279a7ec143c39"},
+ {file = "matplotlib-3.10.9-cp314-cp314t-win_arm64.whl", hash = "sha256:a49f1eadc84ca85fd72fa4e89e70e61bf86452df6f971af04b12c60761a0772c"},
+ {file = "matplotlib-3.10.9-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1872fb212a05b729e649754a72d5da61d03e0554d76e80303b6f83d1d2c0552b"},
+ {file = "matplotlib-3.10.9-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:985f2238880e2e69093f588f5fe2e46771747febf0649f3cf7f7b7480875317f"},
+ {file = "matplotlib-3.10.9-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6640f75af2c6148293caa0a2b39dd806a492dd66c8a8b04035813e33d0fd2585"},
+ {file = "matplotlib-3.10.9-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:42fb814efabe95c06c1994d8ab5a8385f43a249e23badd3ba931d4308e5bca20"},
+ {file = "matplotlib-3.10.9-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:f76e640a5268850bfda54b5131b1b1941cc685e42c5fa98ed9f2d64038308cba"},
+ {file = "matplotlib-3.10.9-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3fc0364dfbe1d07f6d15c5ebd0c5bf89e126916e5a8667dd4a7a6e84c36653d4"},
+ {file = "matplotlib-3.10.9.tar.gz", hash = "sha256:fd66508e8c6877d98e586654b608a0456db8d7e8a546eb1e2600efd957302358"},
+]
+
+[package.dependencies]
+contourpy = ">=1.0.1"
+cycler = ">=0.10"
+fonttools = ">=4.22.0"
+kiwisolver = ">=1.3.1"
+numpy = ">=1.23"
+packaging = ">=20.0"
+pillow = ">=8"
+pyparsing = ">=3"
+python-dateutil = ">=2.7"
+
+[package.extras]
+dev = ["meson-python (>=0.13.1,<0.17.0)", "pybind11 (>=2.13.2,!=2.13.3)", "setuptools (>=64)", "setuptools_scm (>=7,<10)"]
+
+[[package]]
+name = "numpy"
+version = "2.2.6"
+description = "Fundamental package for array computing in Python"
+optional = false
+python-versions = ">=3.10"
+groups = ["main"]
+files = [
+ {file = "numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb"},
+ {file = "numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90"},
+ {file = "numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163"},
+ {file = "numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf"},
+ {file = "numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83"},
+ {file = "numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915"},
+ {file = "numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680"},
+ {file = "numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289"},
+ {file = "numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d"},
+ {file = "numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3"},
+ {file = "numpy-2.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f9f1adb22318e121c5c69a09142811a201ef17ab257a1e66ca3025065b7f53ae"},
+ {file = "numpy-2.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c820a93b0255bc360f53eca31a0e676fd1101f673dda8da93454a12e23fc5f7a"},
+ {file = "numpy-2.2.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3d70692235e759f260c3d837193090014aebdf026dfd167834bcba43e30c2a42"},
+ {file = "numpy-2.2.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:481b49095335f8eed42e39e8041327c05b0f6f4780488f61286ed3c01368d491"},
+ {file = "numpy-2.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b64d8d4d17135e00c8e346e0a738deb17e754230d7e0810ac5012750bbd85a5a"},
+ {file = "numpy-2.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba10f8411898fc418a521833e014a77d3ca01c15b0c6cdcce6a0d2897e6dbbdf"},
+ {file = "numpy-2.2.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bd48227a919f1bafbdda0583705e547892342c26fb127219d60a5c36882609d1"},
+ {file = "numpy-2.2.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9551a499bf125c1d4f9e250377c1ee2eddd02e01eac6644c080162c0c51778ab"},
+ {file = "numpy-2.2.6-cp311-cp311-win32.whl", hash = "sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47"},
+ {file = "numpy-2.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303"},
+ {file = "numpy-2.2.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41c5a21f4a04fa86436124d388f6ed60a9343a6f767fced1a8a71c3fbca038ff"},
+ {file = "numpy-2.2.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de749064336d37e340f640b05f24e9e3dd678c57318c7289d222a8a2f543e90c"},
+ {file = "numpy-2.2.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:894b3a42502226a1cac872f840030665f33326fc3dac8e57c607905773cdcde3"},
+ {file = "numpy-2.2.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:71594f7c51a18e728451bb50cc60a3ce4e6538822731b2933209a1f3614e9282"},
+ {file = "numpy-2.2.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2618db89be1b4e05f7a1a847a9c1c0abd63e63a1607d892dd54668dd92faf87"},
+ {file = "numpy-2.2.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd83c01228a688733f1ded5201c678f0c53ecc1006ffbc404db9f7a899ac6249"},
+ {file = "numpy-2.2.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:37c0ca431f82cd5fa716eca9506aefcabc247fb27ba69c5062a6d3ade8cf8f49"},
+ {file = "numpy-2.2.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fe27749d33bb772c80dcd84ae7e8df2adc920ae8297400dabec45f0dedb3f6de"},
+ {file = "numpy-2.2.6-cp312-cp312-win32.whl", hash = "sha256:4eeaae00d789f66c7a25ac5f34b71a7035bb474e679f410e5e1a94deb24cf2d4"},
+ {file = "numpy-2.2.6-cp312-cp312-win_amd64.whl", hash = "sha256:c1f9540be57940698ed329904db803cf7a402f3fc200bfe599334c9bd84a40b2"},
+ {file = "numpy-2.2.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0811bb762109d9708cca4d0b13c4f67146e3c3b7cf8d34018c722adb2d957c84"},
+ {file = "numpy-2.2.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:287cc3162b6f01463ccd86be154f284d0893d2b3ed7292439ea97eafa8170e0b"},
+ {file = "numpy-2.2.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f1372f041402e37e5e633e586f62aa53de2eac8d98cbfb822806ce4bbefcb74d"},
+ {file = "numpy-2.2.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:55a4d33fa519660d69614a9fad433be87e5252f4b03850642f88993f7b2ca566"},
+ {file = "numpy-2.2.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f92729c95468a2f4f15e9bb94c432a9229d0d50de67304399627a943201baa2f"},
+ {file = "numpy-2.2.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f"},
+ {file = "numpy-2.2.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e3143e4451880bed956e706a3220b4e5cf6172ef05fcc397f6f36a550b1dd868"},
+ {file = "numpy-2.2.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4f13750ce79751586ae2eb824ba7e1e8dba64784086c98cdbbcc6a42112ce0d"},
+ {file = "numpy-2.2.6-cp313-cp313-win32.whl", hash = "sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd"},
+ {file = "numpy-2.2.6-cp313-cp313-win_amd64.whl", hash = "sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c"},
+ {file = "numpy-2.2.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0bca768cd85ae743b2affdc762d617eddf3bcf8724435498a1e80132d04879e6"},
+ {file = "numpy-2.2.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fc0c5673685c508a142ca65209b4e79ed6740a4ed6b2267dbba90f34b0b3cfda"},
+ {file = "numpy-2.2.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:5bd4fc3ac8926b3819797a7c0e2631eb889b4118a9898c84f585a54d475b7e40"},
+ {file = "numpy-2.2.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8"},
+ {file = "numpy-2.2.6-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1dda9c7e08dc141e0247a5b8f49cf05984955246a327d4c48bda16821947b2f"},
+ {file = "numpy-2.2.6-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f447e6acb680fd307f40d3da4852208af94afdfab89cf850986c3ca00562f4fa"},
+ {file = "numpy-2.2.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:389d771b1623ec92636b0786bc4ae56abafad4a4c513d36a55dce14bd9ce8571"},
+ {file = "numpy-2.2.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8e9ace4a37db23421249ed236fdcdd457d671e25146786dfc96835cd951aa7c1"},
+ {file = "numpy-2.2.6-cp313-cp313t-win32.whl", hash = "sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff"},
+ {file = "numpy-2.2.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06"},
+ {file = "numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d"},
+ {file = "numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db"},
+ {file = "numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543"},
+ {file = "numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00"},
+ {file = "numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd"},
+]
+
+[[package]]
+name = "packaging"
+version = "24.1"
+description = "Core utilities for Python packages"
+optional = false
+python-versions = ">=3.8"
+groups = ["main", "dev"]
+files = [
+ {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"},
+ {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"},
+]
+
+[[package]]
+name = "pillow"
+version = "12.2.0"
+description = "Python Imaging Library (fork)"
+optional = false
+python-versions = ">=3.10"
+groups = ["main"]
+files = [
+ {file = "pillow-12.2.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:a4e8f36e677d3336f35089648c8955c51c6d386a13cf6ee9c189c5f5bd713a9f"},
+ {file = "pillow-12.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e589959f10d9824d39b350472b92f0ce3b443c0a3442ebf41c40cb8361c5b97"},
+ {file = "pillow-12.2.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a52edc8bfff4429aaabdf4d9ee0daadbbf8562364f940937b941f87a4290f5ff"},
+ {file = "pillow-12.2.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:975385f4776fafde056abb318f612ef6285b10a1f12b8570f3647ad0d74b48ec"},
+ {file = "pillow-12.2.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bd9c0c7a0c681a347b3194c500cb1e6ca9cab053ea4d82a5cf45b6b754560136"},
+ {file = "pillow-12.2.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:88d387ff40b3ff7c274947ed3125dedf5262ec6919d83946753b5f3d7c67ea4c"},
+ {file = "pillow-12.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:51c4167c34b0d8ba05b547a3bb23578d0ba17b80a5593f93bd8ecb123dd336a3"},
+ {file = "pillow-12.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:34c0d99ecccea270c04882cb3b86e7b57296079c9a4aff88cb3b33563d95afaa"},
+ {file = "pillow-12.2.0-cp310-cp310-win32.whl", hash = "sha256:b85f66ae9eb53e860a873b858b789217ba505e5e405a24b85c0464822fe88032"},
+ {file = "pillow-12.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:673aa32138f3e7531ccdbca7b3901dba9b70940a19ccecc6a37c77d5fdeb05b5"},
+ {file = "pillow-12.2.0-cp310-cp310-win_arm64.whl", hash = "sha256:3e080565d8d7c671db5802eedfb438e5565ffa40115216eabb8cd52d0ecce024"},
+ {file = "pillow-12.2.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:8be29e59487a79f173507c30ddf57e733a357f67881430449bb32614075a40ab"},
+ {file = "pillow-12.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:71cde9a1e1551df7d34a25462fc60325e8a11a82cc2e2f54578e5e9a1e153d65"},
+ {file = "pillow-12.2.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f490f9368b6fc026f021db16d7ec2fbf7d89e2edb42e8ec09d2c60505f5729c7"},
+ {file = "pillow-12.2.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8bd7903a5f2a4545f6fd5935c90058b89d30045568985a71c79f5fd6edf9b91e"},
+ {file = "pillow-12.2.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3997232e10d2920a68d25191392e3a4487d8183039e1c74c2297f00ed1c50705"},
+ {file = "pillow-12.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e74473c875d78b8e9d5da2a70f7099549f9eb37ded4e2f6a463e60125bccd176"},
+ {file = "pillow-12.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:56a3f9c60a13133a98ecff6197af34d7824de9b7b38c3654861a725c970c197b"},
+ {file = "pillow-12.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:90e6f81de50ad6b534cab6e5aef77ff6e37722b2f5d908686f4a5c9eba17a909"},
+ {file = "pillow-12.2.0-cp311-cp311-win32.whl", hash = "sha256:8c984051042858021a54926eb597d6ee3012393ce9c181814115df4c60b9a808"},
+ {file = "pillow-12.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e6b2a0c538fc200b38ff9eb6628228b77908c319a005815f2dde585a0664b60"},
+ {file = "pillow-12.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:9a8a34cc89c67a65ea7437ce257cea81a9dad65b29805f3ecee8c8fe8ff25ffe"},
+ {file = "pillow-12.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2d192a155bbcec180f8564f693e6fd9bccff5a7af9b32e2e4bf8c9c69dbad6b5"},
+ {file = "pillow-12.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f3f40b3c5a968281fd507d519e444c35f0ff171237f4fdde090dd60699458421"},
+ {file = "pillow-12.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:03e7e372d5240cc23e9f07deca4d775c0817bffc641b01e9c3af208dbd300987"},
+ {file = "pillow-12.2.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b86024e52a1b269467a802258c25521e6d742349d760728092e1bc2d135b4d76"},
+ {file = "pillow-12.2.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7371b48c4fa448d20d2714c9a1f775a81155050d383333e0a6c15b1123dda005"},
+ {file = "pillow-12.2.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:62f5409336adb0663b7caa0da5c7d9e7bdbaae9ce761d34669420c2a801b2780"},
+ {file = "pillow-12.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:01afa7cf67f74f09523699b4e88c73fb55c13346d212a59a2db1f86b0a63e8c5"},
+ {file = "pillow-12.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fc3d34d4a8fbec3e88a79b92e5465e0f9b842b628675850d860b8bd300b159f5"},
+ {file = "pillow-12.2.0-cp312-cp312-win32.whl", hash = "sha256:58f62cc0f00fd29e64b29f4fd923ffdb3859c9f9e6105bfc37ba1d08994e8940"},
+ {file = "pillow-12.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:7f84204dee22a783350679a0333981df803dac21a0190d706a50475e361c93f5"},
+ {file = "pillow-12.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:af73337013e0b3b46f175e79492d96845b16126ddf79c438d7ea7ff27783a414"},
+ {file = "pillow-12.2.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:8297651f5b5679c19968abefd6bb84d95fe30ef712eb1b2d9b2d31ca61267f4c"},
+ {file = "pillow-12.2.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:50d8520da2a6ce0af445fa6d648c4273c3eeefbc32d7ce049f22e8b5c3daecc2"},
+ {file = "pillow-12.2.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:766cef22385fa1091258ad7e6216792b156dc16d8d3fa607e7545b2b72061f1c"},
+ {file = "pillow-12.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5d2fd0fa6b5d9d1de415060363433f28da8b1526c1c129020435e186794b3795"},
+ {file = "pillow-12.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:56b25336f502b6ed02e889f4ece894a72612fe885889a6e8c4c80239ff6e5f5f"},
+ {file = "pillow-12.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f1c943e96e85df3d3478f7b691f229887e143f81fedab9b20205349ab04d73ed"},
+ {file = "pillow-12.2.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:03f6fab9219220f041c74aeaa2939ff0062bd5c364ba9ce037197f4c6d498cd9"},
+ {file = "pillow-12.2.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5cdfebd752ec52bf5bb4e35d9c64b40826bc5b40a13df7c3cda20a2c03a0f5ed"},
+ {file = "pillow-12.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eedf4b74eda2b5a4b2b2fb4c006d6295df3bf29e459e198c90ea48e130dc75c3"},
+ {file = "pillow-12.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:00a2865911330191c0b818c59103b58a5e697cae67042366970a6b6f1b20b7f9"},
+ {file = "pillow-12.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1e1757442ed87f4912397c6d35a0db6a7b52592156014706f17658ff58bbf795"},
+ {file = "pillow-12.2.0-cp313-cp313-win32.whl", hash = "sha256:144748b3af2d1b358d41286056d0003f47cb339b8c43a9ea42f5fea4d8c66b6e"},
+ {file = "pillow-12.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:390ede346628ccc626e5730107cde16c42d3836b89662a115a921f28440e6a3b"},
+ {file = "pillow-12.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:8023abc91fba39036dbce14a7d6535632f99c0b857807cbbbf21ecc9f4717f06"},
+ {file = "pillow-12.2.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:042db20a421b9bafecc4b84a8b6e444686bd9d836c7fd24542db3e7df7baad9b"},
+ {file = "pillow-12.2.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:dd025009355c926a84a612fecf58bb315a3f6814b17ead51a8e48d3823d9087f"},
+ {file = "pillow-12.2.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:88ddbc66737e277852913bd1e07c150cc7bb124539f94c4e2df5344494e0a612"},
+ {file = "pillow-12.2.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d362d1878f00c142b7e1a16e6e5e780f02be8195123f164edf7eddd911eefe7c"},
+ {file = "pillow-12.2.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2c727a6d53cb0018aadd8018c2b938376af27914a68a492f59dfcaca650d5eea"},
+ {file = "pillow-12.2.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:efd8c21c98c5cc60653bcb311bef2ce0401642b7ce9d09e03a7da87c878289d4"},
+ {file = "pillow-12.2.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9f08483a632889536b8139663db60f6724bfcb443c96f1b18855860d7d5c0fd4"},
+ {file = "pillow-12.2.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dac8d77255a37e81a2efcbd1fc05f1c15ee82200e6c240d7e127e25e365c39ea"},
+ {file = "pillow-12.2.0-cp313-cp313t-win32.whl", hash = "sha256:ee3120ae9dff32f121610bb08e4313be87e03efeadfc6c0d18f89127e24d0c24"},
+ {file = "pillow-12.2.0-cp313-cp313t-win_amd64.whl", hash = "sha256:325ca0528c6788d2a6c3d40e3568639398137346c3d6e66bb61db96b96511c98"},
+ {file = "pillow-12.2.0-cp313-cp313t-win_arm64.whl", hash = "sha256:2e5a76d03a6c6dcef67edabda7a52494afa4035021a79c8558e14af25313d453"},
+ {file = "pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:3adc9215e8be0448ed6e814966ecf3d9952f0ea40eb14e89a102b87f450660d8"},
+ {file = "pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:6a9adfc6d24b10f89588096364cc726174118c62130c817c2837c60cf08a392b"},
+ {file = "pillow-12.2.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:6a6e67ea2e6feda684ed370f9a1c52e7a243631c025ba42149a2cc5934dec295"},
+ {file = "pillow-12.2.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2bb4a8d594eacdfc59d9e5ad972aa8afdd48d584ffd5f13a937a664c3e7db0ed"},
+ {file = "pillow-12.2.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:80b2da48193b2f33ed0c32c38140f9d3186583ce7d516526d462645fd98660ae"},
+ {file = "pillow-12.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22db17c68434de69d8ecfc2fe821569195c0c373b25cccb9cbdacf2c6e53c601"},
+ {file = "pillow-12.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7b14cc0106cd9aecda615dd6903840a058b4700fcb817687d0ee4fc8b6e389be"},
+ {file = "pillow-12.2.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cbeb542b2ebc6fcdacabf8aca8c1a97c9b3ad3927d46b8723f9d4f033288a0f"},
+ {file = "pillow-12.2.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4bfd07bc812fbd20395212969e41931001fd59eb55a60658b0e5710872e95286"},
+ {file = "pillow-12.2.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9aba9a17b623ef750a4d11b742cbafffeb48a869821252b30ee21b5e91392c50"},
+ {file = "pillow-12.2.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:deede7c263feb25dba4e82ea23058a235dcc2fe1f6021025dc71f2b618e26104"},
+ {file = "pillow-12.2.0-cp314-cp314-win32.whl", hash = "sha256:632ff19b2778e43162304d50da0181ce24ac5bb8180122cbe1bf4673428328c7"},
+ {file = "pillow-12.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:4e6c62e9d237e9b65fac06857d511e90d8461a32adcc1b9065ea0c0fa3a28150"},
+ {file = "pillow-12.2.0-cp314-cp314-win_arm64.whl", hash = "sha256:b1c1fbd8a5a1af3412a0810d060a78b5136ec0836c8a4ef9aa11807f2a22f4e1"},
+ {file = "pillow-12.2.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:57850958fe9c751670e49b2cecf6294acc99e562531f4bd317fa5ddee2068463"},
+ {file = "pillow-12.2.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d5d38f1411c0ed9f97bcb49b7bd59b6b7c314e0e27420e34d99d844b9ce3b6f3"},
+ {file = "pillow-12.2.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5c0a9f29ca8e79f09de89293f82fc9b0270bb4af1d58bc98f540cc4aedf03166"},
+ {file = "pillow-12.2.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1610dd6c61621ae1cf811bef44d77e149ce3f7b95afe66a4512f8c59f25d9ebe"},
+ {file = "pillow-12.2.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a34329707af4f73cf1782a36cd2289c0368880654a2c11f027bcee9052d35dd"},
+ {file = "pillow-12.2.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e9c4f5b3c546fa3458a29ab22646c1c6c787ea8f5ef51300e5a60300736905e"},
+ {file = "pillow-12.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:fb043ee2f06b41473269765c2feae53fc2e2fbf96e5e22ca94fb5ad677856f06"},
+ {file = "pillow-12.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f278f034eb75b4e8a13a54a876cc4a5ab39173d2cdd93a638e1b467fc545ac43"},
+ {file = "pillow-12.2.0-cp314-cp314t-win32.whl", hash = "sha256:6bb77b2dcb06b20f9f4b4a8454caa581cd4dd0643a08bacf821216a16d9c8354"},
+ {file = "pillow-12.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:6562ace0d3fb5f20ed7290f1f929cae41b25ae29528f2af1722966a0a02e2aa1"},
+ {file = "pillow-12.2.0-cp314-cp314t-win_arm64.whl", hash = "sha256:aa88ccfe4e32d362816319ed727a004423aab09c5cea43c01a4b435643fa34eb"},
+ {file = "pillow-12.2.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0538bd5e05efec03ae613fd89c4ce0368ecd2ba239cc25b9f9be7ed426b0af1f"},
+ {file = "pillow-12.2.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:394167b21da716608eac917c60aa9b969421b5dcbbe02ae7f013e7b85811c69d"},
+ {file = "pillow-12.2.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5d04bfa02cc2d23b497d1e90a0f927070043f6cbf303e738300532379a4b4e0f"},
+ {file = "pillow-12.2.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0c838a5125cee37e68edec915651521191cef1e6aa336b855f495766e77a366e"},
+ {file = "pillow-12.2.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a6c9fa44005fa37a91ebfc95d081e8079757d2e904b27103f4f5fa6f0bf78c0"},
+ {file = "pillow-12.2.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:25373b66e0dd5905ed63fa3cae13c82fbddf3079f2c8bf15c6fb6a35586324c1"},
+ {file = "pillow-12.2.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:bfa9c230d2fe991bed5318a5f119bd6780cda2915cca595393649fc118ab895e"},
+ {file = "pillow-12.2.0.tar.gz", hash = "sha256:a830b1a40919539d07806aa58e1b114df53ddd43213d9c8b75847eee6c0182b5"},
+]
+
+[package.extras]
+docs = ["furo", "olefile", "sphinx (>=8.2)", "sphinx-autobuild", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"]
+fpx = ["olefile"]
+mic = ["olefile"]
+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]]
+name = "pluggy"
+version = "1.5.0"
+description = "plugin and hook calling mechanisms for python"
+optional = false
+python-versions = ">=3.8"
+groups = ["dev"]
+files = [
+ {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"},
+ {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"},
+]
+
+[package.extras]
+dev = ["pre-commit", "tox"]
+testing = ["pytest", "pytest-benchmark"]
+
+[[package]]
+name = "pydantic"
+version = "2.9.2"
+description = "Data validation using Python type hints"
+optional = false
+python-versions = ">=3.8"
+groups = ["main"]
+files = [
+ {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"},
+ {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"},
+]
+
+[package.dependencies]
+annotated-types = ">=0.6.0"
+pydantic-core = "2.23.4"
+typing-extensions = [
+ {version = ">=4.12.2", markers = "python_version >= \"3.13\""},
+ {version = ">=4.6.1", markers = "python_version < \"3.13\""},
+]
+
+[package.extras]
+email = ["email-validator (>=2.0.0)"]
+timezone = ["tzdata ; python_version >= \"3.9\" and sys_platform == \"win32\""]
+
+[[package]]
+name = "pydantic-core"
+version = "2.23.4"
+description = "Core functionality for Pydantic validation and serialization"
+optional = false
+python-versions = ">=3.8"
+groups = ["main"]
+files = [
+ {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"},
+ {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"},
+ {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"},
+ {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"},
+ {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"},
+ {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"},
+ {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"},
+ {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"},
+ {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"},
+ {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"},
+ {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"},
+ {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"},
+ {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"},
+ {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"},
+ {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"},
+ {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"},
+ {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"},
+ {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"},
+ {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"},
+ {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"},
+ {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"},
+ {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"},
+ {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"},
+ {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"},
+ {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"},
+ {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"},
+ {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"},
+ {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"},
+ {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"},
+ {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"},
+ {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"},
+ {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"},
+ {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"},
+ {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"},
+ {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"},
+ {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"},
+ {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"},
+ {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"},
+ {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"},
+ {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"},
+ {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"},
+ {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"},
+ {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"},
+ {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"},
+ {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"},
+ {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"},
+ {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"},
+ {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"},
+ {file = "pydantic_core-2.23.4-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d4488a93b071c04dc20f5cecc3631fc78b9789dd72483ba15d423b5b3689b555"},
+ {file = "pydantic_core-2.23.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:81965a16b675b35e1d09dd14df53f190f9129c0202356ed44ab2728b1c905658"},
+ {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffa2ebd4c8530079140dd2d7f794a9d9a73cbb8e9d59ffe24c63436efa8f271"},
+ {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61817945f2fe7d166e75fbfb28004034b48e44878177fc54d81688e7b85a3665"},
+ {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d2c342c4bc01b88402d60189f3df065fb0dda3654744d5a165a5288a657368"},
+ {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e11661ce0fd30a6790e8bcdf263b9ec5988e95e63cf901972107efc49218b13"},
+ {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d18368b137c6295db49ce7218b1a9ba15c5bc254c96d7c9f9e924a9bc7825ad"},
+ {file = "pydantic_core-2.23.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec4e55f79b1c4ffb2eecd8a0cfba9955a2588497d96851f4c8f99aa4a1d39b12"},
+ {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:374a5e5049eda9e0a44c696c7ade3ff355f06b1fe0bb945ea3cac2bc336478a2"},
+ {file = "pydantic_core-2.23.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5c364564d17da23db1106787675fc7af45f2f7b58b4173bfdd105564e132e6fb"},
+ {file = "pydantic_core-2.23.4-cp38-none-win32.whl", hash = "sha256:d7a80d21d613eec45e3d41eb22f8f94ddc758a6c4720842dc74c0581f54993d6"},
+ {file = "pydantic_core-2.23.4-cp38-none-win_amd64.whl", hash = "sha256:5f5ff8d839f4566a474a969508fe1c5e59c31c80d9e140566f9a37bba7b8d556"},
+ {file = "pydantic_core-2.23.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a4fa4fc04dff799089689f4fd502ce7d59de529fc2f40a2c8836886c03e0175a"},
+ {file = "pydantic_core-2.23.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0a7df63886be5e270da67e0966cf4afbae86069501d35c8c1b3b6c168f42cb36"},
+ {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcedcd19a557e182628afa1d553c3895a9f825b936415d0dbd3cd0bbcfd29b4b"},
+ {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f54b118ce5de9ac21c363d9b3caa6c800341e8c47a508787e5868c6b79c9323"},
+ {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86d2f57d3e1379a9525c5ab067b27dbb8a0642fb5d454e17a9ac434f9ce523e3"},
+ {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:de6d1d1b9e5101508cb37ab0d972357cac5235f5c6533d1071964c47139257df"},
+ {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1278e0d324f6908e872730c9102b0112477a7f7cf88b308e4fc36ce1bdb6d58c"},
+ {file = "pydantic_core-2.23.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9a6b5099eeec78827553827f4c6b8615978bb4b6a88e5d9b93eddf8bb6790f55"},
+ {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e55541f756f9b3ee346b840103f32779c695a19826a4c442b7954550a0972040"},
+ {file = "pydantic_core-2.23.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a5c7ba8ffb6d6f8f2ab08743be203654bb1aaa8c9dcb09f82ddd34eadb695605"},
+ {file = "pydantic_core-2.23.4-cp39-none-win32.whl", hash = "sha256:37b0fe330e4a58d3c58b24d91d1eb102aeec675a3db4c292ec3928ecd892a9a6"},
+ {file = "pydantic_core-2.23.4-cp39-none-win_amd64.whl", hash = "sha256:1498bec4c05c9c787bde9125cfdcc63a41004ff167f495063191b863399b1a29"},
+ {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"},
+ {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"},
+ {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"},
+ {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"},
+ {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"},
+ {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"},
+ {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"},
+ {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"},
+ {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:78ddaaa81421a29574a682b3179d4cf9e6d405a09b99d93ddcf7e5239c742e21"},
+ {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:883a91b5dd7d26492ff2f04f40fbb652de40fcc0afe07e8129e8ae779c2110eb"},
+ {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88ad334a15b32a791ea935af224b9de1bf99bcd62fabf745d5f3442199d86d59"},
+ {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:233710f069d251feb12a56da21e14cca67994eab08362207785cf8c598e74577"},
+ {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19442362866a753485ba5e4be408964644dd6a09123d9416c54cd49171f50744"},
+ {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:624e278a7d29b6445e4e813af92af37820fafb6dcc55c012c834f9e26f9aaaef"},
+ {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f5ef8f42bec47f21d07668a043f077d507e5bf4e668d5c6dfe6aaba89de1a5b8"},
+ {file = "pydantic_core-2.23.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:aea443fffa9fbe3af1a9ba721a87f926fe548d32cab71d188a6ede77d0ff244e"},
+ {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"},
+]
+
+[package.dependencies]
+typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0"
+
+[[package]]
+name = "pygments"
+version = "2.20.0"
+description = "Pygments is a syntax highlighting package written in Python."
+optional = false
+python-versions = ">=3.9"
+groups = ["dev"]
+files = [
+ {file = "pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176"},
+ {file = "pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f"},
+]
+
+[package.extras]
+windows-terminal = ["colorama (>=0.4.6)"]
+
+[[package]]
+name = "pyparsing"
+version = "3.2.0"
+description = "pyparsing module - Classes and methods to define and execute parsing grammars"
+optional = false
+python-versions = ">=3.9"
+groups = ["main"]
+files = [
+ {file = "pyparsing-3.2.0-py3-none-any.whl", hash = "sha256:93d9577b88da0bbea8cc8334ee8b918ed014968fd2ec383e868fb8afb1ccef84"},
+ {file = "pyparsing-3.2.0.tar.gz", hash = "sha256:cbf74e27246d595d9a74b186b810f6fbb86726dbf3b9532efb343f6d7294fe9c"},
+]
+
+[package.extras]
+diagrams = ["jinja2", "railroad-diagrams"]
+
+[[package]]
+name = "pytest"
+version = "9.0.3"
+description = "pytest: simple powerful testing with Python"
+optional = false
+python-versions = ">=3.10"
+groups = ["dev"]
+files = [
+ {file = "pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9"},
+ {file = "pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c"},
+]
+
+[package.dependencies]
+colorama = {version = ">=0.4", markers = "sys_platform == \"win32\""}
+exceptiongroup = {version = ">=1", markers = "python_version < \"3.11\""}
+iniconfig = ">=1.0.1"
+packaging = ">=22"
+pluggy = ">=1.5,<2"
+pygments = ">=2.7.2"
+tomli = {version = ">=1", markers = "python_version < \"3.11\""}
+
+[package.extras]
+dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests", "setuptools", "xmlschema"]
+
+[[package]]
+name = "pytest-dotenv"
+version = "0.5.2"
+description = "A py.test plugin that parses environment files before running tests"
+optional = false
+python-versions = "*"
+groups = ["dev"]
+files = [
+ {file = "pytest-dotenv-0.5.2.tar.gz", hash = "sha256:2dc6c3ac6d8764c71c6d2804e902d0ff810fa19692e95fe138aefc9b1aa73732"},
+ {file = "pytest_dotenv-0.5.2-py3-none-any.whl", hash = "sha256:40a2cece120a213898afaa5407673f6bd924b1fa7eafce6bda0e8abffe2f710f"},
+]
+
+[package.dependencies]
+pytest = ">=5.0.0"
+python-dotenv = ">=0.9.1"
+
+[[package]]
+name = "python-dateutil"
+version = "2.9.0.post0"
+description = "Extensions to the standard Python datetime module"
+optional = false
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
+groups = ["main"]
+files = [
+ {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"},
+ {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"},
+]
+
+[package.dependencies]
+six = ">=1.5"
+
+[[package]]
+name = "python-dotenv"
+version = "1.2.2"
+description = "Read key-value pairs from a .env file and set them as environment variables"
+optional = false
+python-versions = ">=3.10"
+groups = ["dev"]
+files = [
+ {file = "python_dotenv-1.2.2-py3-none-any.whl", hash = "sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a"},
+ {file = "python_dotenv-1.2.2.tar.gz", hash = "sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3"},
+]
+
+[package.extras]
+cli = ["click (>=5.0)"]
+
+[[package]]
+name = "ruff"
+version = "0.11.13"
+description = "An extremely fast Python linter and code formatter, written in Rust."
+optional = false
+python-versions = ">=3.7"
+groups = ["dev"]
+files = [
+ {file = "ruff-0.11.13-py3-none-linux_armv6l.whl", hash = "sha256:4bdfbf1240533f40042ec00c9e09a3aade6f8c10b6414cf11b519488d2635d46"},
+ {file = "ruff-0.11.13-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:aef9c9ed1b5ca28bb15c7eac83b8670cf3b20b478195bd49c8d756ba0a36cf48"},
+ {file = "ruff-0.11.13-py3-none-macosx_11_0_arm64.whl", hash = "sha256:53b15a9dfdce029c842e9a5aebc3855e9ab7771395979ff85b7c1dedb53ddc2b"},
+ {file = "ruff-0.11.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab153241400789138d13f362c43f7edecc0edfffce2afa6a68434000ecd8f69a"},
+ {file = "ruff-0.11.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6c51f93029d54a910d3d24f7dd0bb909e31b6cd989a5e4ac513f4eb41629f0dc"},
+ {file = "ruff-0.11.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1808b3ed53e1a777c2ef733aca9051dc9bf7c99b26ece15cb59a0320fbdbd629"},
+ {file = "ruff-0.11.13-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d28ce58b5ecf0f43c1b71edffabe6ed7f245d5336b17805803312ec9bc665933"},
+ {file = "ruff-0.11.13-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55e4bc3a77842da33c16d55b32c6cac1ec5fb0fbec9c8c513bdce76c4f922165"},
+ {file = "ruff-0.11.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:633bf2c6f35678c56ec73189ba6fa19ff1c5e4807a78bf60ef487b9dd272cc71"},
+ {file = "ruff-0.11.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ffbc82d70424b275b089166310448051afdc6e914fdab90e08df66c43bb5ca9"},
+ {file = "ruff-0.11.13-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4a9ddd3ec62a9a89578c85842b836e4ac832d4a2e0bfaad3b02243f930ceafcc"},
+ {file = "ruff-0.11.13-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d237a496e0778d719efb05058c64d28b757c77824e04ffe8796c7436e26712b7"},
+ {file = "ruff-0.11.13-py3-none-musllinux_1_2_i686.whl", hash = "sha256:26816a218ca6ef02142343fd24c70f7cd8c5aa6c203bca284407adf675984432"},
+ {file = "ruff-0.11.13-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:51c3f95abd9331dc5b87c47ac7f376db5616041173826dfd556cfe3d4977f492"},
+ {file = "ruff-0.11.13-py3-none-win32.whl", hash = "sha256:96c27935418e4e8e77a26bb05962817f28b8ef3843a6c6cc49d8783b5507f250"},
+ {file = "ruff-0.11.13-py3-none-win_amd64.whl", hash = "sha256:29c3189895a8a6a657b7af4e97d330c8a3afd2c9c8f46c81e2fc5a31866517e3"},
+ {file = "ruff-0.11.13-py3-none-win_arm64.whl", hash = "sha256:b4385285e9179d608ff1d2fb9922062663c658605819a6876d8beef0c30b7f3b"},
+ {file = "ruff-0.11.13.tar.gz", hash = "sha256:26fa247dc68d1d4e72c179e08889a25ac0c7ba4d78aecfc835d49cbfd60bf514"},
+]
+
+[[package]]
+name = "six"
+version = "1.16.0"
+description = "Python 2 and 3 compatibility utilities"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
+groups = ["main"]
+files = [
+ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
+ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
+]
+
+[[package]]
+name = "tomli"
+version = "2.4.0"
+description = "A lil' TOML parser"
+optional = false
+python-versions = ">=3.8"
+groups = ["dev"]
+markers = "python_version == \"3.10\""
+files = [
+ {file = "tomli-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867"},
+ {file = "tomli-2.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9"},
+ {file = "tomli-2.4.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95"},
+ {file = "tomli-2.4.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76"},
+ {file = "tomli-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d"},
+ {file = "tomli-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576"},
+ {file = "tomli-2.4.0-cp311-cp311-win32.whl", hash = "sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a"},
+ {file = "tomli-2.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa"},
+ {file = "tomli-2.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614"},
+ {file = "tomli-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1"},
+ {file = "tomli-2.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8"},
+ {file = "tomli-2.4.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a"},
+ {file = "tomli-2.4.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1"},
+ {file = "tomli-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b"},
+ {file = "tomli-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51"},
+ {file = "tomli-2.4.0-cp312-cp312-win32.whl", hash = "sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729"},
+ {file = "tomli-2.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da"},
+ {file = "tomli-2.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3"},
+ {file = "tomli-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0"},
+ {file = "tomli-2.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e"},
+ {file = "tomli-2.4.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4"},
+ {file = "tomli-2.4.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e"},
+ {file = "tomli-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c"},
+ {file = "tomli-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f"},
+ {file = "tomli-2.4.0-cp313-cp313-win32.whl", hash = "sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86"},
+ {file = "tomli-2.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87"},
+ {file = "tomli-2.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132"},
+ {file = "tomli-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6"},
+ {file = "tomli-2.4.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc"},
+ {file = "tomli-2.4.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66"},
+ {file = "tomli-2.4.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d"},
+ {file = "tomli-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702"},
+ {file = "tomli-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8"},
+ {file = "tomli-2.4.0-cp314-cp314-win32.whl", hash = "sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776"},
+ {file = "tomli-2.4.0-cp314-cp314-win_amd64.whl", hash = "sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475"},
+ {file = "tomli-2.4.0-cp314-cp314-win_arm64.whl", hash = "sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2"},
+ {file = "tomli-2.4.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9"},
+ {file = "tomli-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0"},
+ {file = "tomli-2.4.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df"},
+ {file = "tomli-2.4.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d"},
+ {file = "tomli-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f"},
+ {file = "tomli-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b"},
+ {file = "tomli-2.4.0-cp314-cp314t-win32.whl", hash = "sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087"},
+ {file = "tomli-2.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd"},
+ {file = "tomli-2.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4"},
+ {file = "tomli-2.4.0-py3-none-any.whl", hash = "sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a"},
+ {file = "tomli-2.4.0.tar.gz", hash = "sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c"},
+]
+
+[[package]]
+name = "typing-extensions"
+version = "4.12.2"
+description = "Backported and Experimental Type Hints for Python 3.8+"
+optional = false
+python-versions = ">=3.8"
+groups = ["main", "dev"]
+files = [
+ {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
+ {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
+]
+markers = {dev = "python_version == \"3.10\""}
+
+[metadata]
+lock-version = "2.1"
+python-versions = "^3.10"
+content-hash = "3cc28939d00ff71865731a15db02967ee9edafb37daa70de9a9e1be1c397ac18"
diff --git a/chart_data_extractor/pyproject.toml b/chart_data_extractor/pyproject.toml
new file mode 100644
index 00000000..66cf7255
--- /dev/null
+++ b/chart_data_extractor/pyproject.toml
@@ -0,0 +1,34 @@
+[tool.poetry]
+name = "e2b-charts"
+version = "1.0.0"
+description = "Package for extracting data for E2B Code Interpreter"
+authors = ["e2b "]
+license = "MIT"
+readme = "README.md"
+homepage = "https://e2b.dev/"
+repository = "https://github.com/e2b-dev/e2b-code-interpreter/tree/python"
+packages = [{ include = "e2b_charts" }]
+
+[tool.poetry.dependencies]
+python = "^3.10"
+
+numpy = "^2.2.6"
+matplotlib = "^3.10.3"
+pydantic = "^2.9.1"
+
+[tool.poetry.group.dev.dependencies]
+pytest = "^9.0.3"
+python-dotenv = "^1.2.1"
+pytest-dotenv = "^0.5.2"
+ruff = "^0.11.12"
+
+
+[build-system]
+requires = ["poetry-core"]
+build-backend = "poetry.core.masonry.api"
+
+[tool.poetry.urls]
+"Bug Tracker" = "https://github.com/e2b-dev/code-interpreter/issues"
+
+[tool.ruff.lint]
+ignore = ["F401", "F403"]
diff --git a/chart_data_extractor/tests/charts/test_bar.py b/chart_data_extractor/tests/charts/test_bar.py
new file mode 100644
index 00000000..246b4d62
--- /dev/null
+++ b/chart_data_extractor/tests/charts/test_bar.py
@@ -0,0 +1,49 @@
+import matplotlib.pyplot as plt
+
+from e2b_charts import chart_figure_to_chart
+from e2b_charts.charts import BarChart, ChartType
+
+
+def _prep_chart_figure():
+ # Prepare data
+ authors = ["Author A", "Author B", "Author C", "Author D"]
+ sales = [100, 200, 300, 400]
+
+ # Create and customize the bar chart
+ plt.figure(figsize=(10, 6))
+ plt.bar(authors, sales, label="Books Sold", color="blue")
+ plt.xlabel("Authors")
+ plt.ylabel("Number of Books Sold")
+ plt.title("Book Sales by Authors")
+
+ # Display the chart
+ plt.tight_layout()
+ return plt.gcf()
+
+
+def test_chart_bar():
+ figure = _prep_chart_figure()
+ chart = chart_figure_to_chart(figure)
+ assert chart
+
+ assert isinstance(chart, BarChart)
+ assert chart.type == ChartType.BAR
+ assert chart.title == "Book Sales by Authors"
+
+ assert chart.x_label == "Authors"
+ assert chart.y_label == "Number of Books Sold"
+
+ assert chart.x_unit is None
+ assert chart.y_unit is None
+
+ bars = chart.elements
+ assert len(bars) == 4
+
+ assert [bar.value for bar in bars] == [100, 200, 300, 400]
+ assert [bar.label for bar in bars] == [
+ "Author A",
+ "Author B",
+ "Author C",
+ "Author D",
+ ]
+ assert [bar.group for bar in bars] == ["Books Sold"] * 4
diff --git a/chart_data_extractor/tests/charts/test_blank.py b/chart_data_extractor/tests/charts/test_blank.py
new file mode 100644
index 00000000..7fb95c43
--- /dev/null
+++ b/chart_data_extractor/tests/charts/test_blank.py
@@ -0,0 +1,9 @@
+import matplotlib.pyplot as plt
+
+from e2b_charts import chart_figure_to_chart
+
+
+def test_blank_chart():
+ figure, _ = plt.subplots()
+ chart = chart_figure_to_chart(figure)
+ assert chart is None
diff --git a/chart_data_extractor/tests/charts/test_box_and_whiskers.py b/chart_data_extractor/tests/charts/test_box_and_whiskers.py
new file mode 100644
index 00000000..799e3ffd
--- /dev/null
+++ b/chart_data_extractor/tests/charts/test_box_and_whiskers.py
@@ -0,0 +1,57 @@
+import matplotlib.pyplot as plt
+
+from e2b_charts import chart_figure_to_chart
+from e2b_charts.charts import BoxAndWhiskerChart, ChartType
+
+
+def _prep_chart_figure():
+ # Sample data
+ data = {
+ "Class A": [85, 90, 78, 92, 88],
+ "Class B": [95, 89, 76, 91, 84, 87],
+ "Class C": [75, 82, 88, 79, 86],
+ }
+
+ # Create figure and axis
+ fig, ax = plt.subplots(figsize=(10, 6))
+
+ # Plot box plot
+ ax.boxplot(data.values(), tick_labels=data.keys())
+
+ # Customize plot
+ ax.set_title("Exam Scores Distribution")
+ ax.set_xlabel("Class")
+ ax.set_ylabel("Score")
+
+ # Set custom colors
+ ax.boxplot(data.values(), tick_labels=data.keys(), patch_artist=True)
+
+ # Adjust layout and show plot
+ plt.tight_layout()
+ return plt.gcf()
+
+
+def test_box_and_whiskers():
+ figure = _prep_chart_figure()
+ chart = chart_figure_to_chart(figure)
+ assert chart
+
+ assert isinstance(chart, BoxAndWhiskerChart)
+ assert chart.type == ChartType.BOX_AND_WHISKER
+ assert chart.title == "Exam Scores Distribution"
+
+ assert chart.x_label == "Class"
+ assert chart.y_label == "Score"
+
+ assert chart.x_unit is None
+ assert chart.y_unit is None
+
+ bars = chart.elements
+ assert len(bars) == 3
+
+ assert all(isinstance(bar.min, float) for bar in bars)
+ assert all(isinstance(bar.first_quartile, float) for bar in bars)
+ assert all(isinstance(bar.median, float) for bar in bars)
+ assert all(isinstance(bar.third_quartile, float) for bar in bars)
+ assert all(isinstance(bar.max, float) for bar in bars)
+ assert all(isinstance(bar.label, str) for bar in bars)
diff --git a/chart_data_extractor/tests/charts/test_categorical_scale.py b/chart_data_extractor/tests/charts/test_categorical_scale.py
new file mode 100644
index 00000000..12d87d23
--- /dev/null
+++ b/chart_data_extractor/tests/charts/test_categorical_scale.py
@@ -0,0 +1,25 @@
+import matplotlib.pyplot as plt
+
+from e2b_charts import chart_figure_to_chart
+from e2b_charts.charts import LineChart
+
+
+def _prep_chart_figure():
+ x = [1, 2, 3, 4, 5]
+ y = ["A", "B", "C", "D", "E"]
+
+ # Create the plot
+ plt.figure(figsize=(10, 6))
+ plt.plot(x, y)
+
+ return plt.gcf()
+
+
+def test_categorical_scale():
+ figure = _prep_chart_figure()
+ chart = chart_figure_to_chart(figure)
+ assert chart
+
+ assert isinstance(chart, LineChart)
+ assert chart.x_scale == "linear"
+ assert chart.y_scale == "categorical"
diff --git a/chart_data_extractor/tests/charts/test_datetime_scale.py b/chart_data_extractor/tests/charts/test_datetime_scale.py
new file mode 100644
index 00000000..a851d16b
--- /dev/null
+++ b/chart_data_extractor/tests/charts/test_datetime_scale.py
@@ -0,0 +1,30 @@
+import numpy as np
+import matplotlib.pyplot as plt
+import datetime
+
+from e2b_charts import chart_figure_to_chart
+from e2b_charts.charts import LineChart
+
+
+def _prep_chart_figure():
+ # Generate x values
+ dates = [
+ datetime.date(2023, 9, 1) + datetime.timedelta(seconds=i) for i in range(100)
+ ]
+ y_sin = np.sin(np.linspace(0, 2 * np.pi, 100))
+
+ # Create the plot
+ plt.figure(figsize=(10, 6))
+ plt.plot(dates, y_sin, label="sin(x)")
+
+ return plt.gcf()
+
+
+def test_datetime_scale():
+ figure = _prep_chart_figure()
+ chart = chart_figure_to_chart(figure)
+ assert chart
+
+ assert isinstance(chart, LineChart)
+ assert chart.x_scale == "datetime"
+ assert chart.y_scale == "linear"
diff --git a/chart_data_extractor/tests/charts/test_line.py b/chart_data_extractor/tests/charts/test_line.py
new file mode 100644
index 00000000..ed58e655
--- /dev/null
+++ b/chart_data_extractor/tests/charts/test_line.py
@@ -0,0 +1,74 @@
+import numpy as np
+import matplotlib.pyplot as plt
+import datetime
+
+from e2b_charts import chart_figure_to_chart
+from e2b_charts.charts import LineChart
+
+
+def _prep_chart_figure():
+ # Generate x values
+ dates = [
+ datetime.date(2023, 9, 1) + datetime.timedelta(seconds=i) for i in range(100)
+ ]
+
+ x = np.linspace(0, 2 * np.pi, 100)
+ # Calculate y values
+ y_sin = np.sin(x)
+ y_cos = np.cos(x)
+
+ # Create the plot
+ plt.figure(figsize=(10, 6))
+ plt.plot(dates, y_sin, label="sin(x)")
+ plt.plot(dates, y_cos, label="cos(x)")
+
+ # Add labels and title
+ plt.xlabel("Time (s)")
+ plt.ylabel("Amplitude (Hz)")
+ plt.title("Plot of sin(x) and cos(x)")
+
+ return plt.gcf()
+
+
+def test_line_chart():
+ figure = _prep_chart_figure()
+ chart = chart_figure_to_chart(figure)
+ assert chart
+
+ assert isinstance(chart, LineChart)
+ assert chart.title == "Plot of sin(x) and cos(x)"
+
+ assert chart.x_label == "Time (s)"
+ assert chart.y_label == "Amplitude (Hz)"
+
+ assert chart.x_unit == "s"
+ assert chart.y_unit == "Hz"
+
+ assert chart.x_scale == "datetime"
+ assert chart.y_scale == "linear"
+
+ assert all(isinstance(x, str) for x in chart.x_ticks)
+ parsed_date = datetime.datetime.fromisoformat(chart.x_ticks[0])
+ assert isinstance(parsed_date, datetime.datetime)
+ assert all(isinstance(y, float) for y in chart.y_ticks)
+
+ assert all(isinstance(x, str) for x in chart.y_tick_labels)
+ assert all(isinstance(y, str) for y in chart.y_tick_labels)
+
+ lines = chart.elements
+ assert len(lines) == 2
+
+ first_line = lines[0]
+ assert first_line.label == "sin(x)"
+ assert len(first_line.points) == 100
+ assert all(isinstance(point, tuple) for point in first_line.points)
+ assert all(
+ isinstance(x, str) and isinstance(y, float) for x, y in first_line.points
+ )
+
+ parsed_date = datetime.datetime.fromisoformat(first_line.points[0][0])
+ assert isinstance(parsed_date, datetime.datetime)
+
+ second_line = lines[1]
+ assert second_line.label == "cos(x)"
+ assert len(second_line.points) == 100
diff --git a/chart_data_extractor/tests/charts/test_log_graph.py b/chart_data_extractor/tests/charts/test_log_graph.py
new file mode 100644
index 00000000..b15cb72b
--- /dev/null
+++ b/chart_data_extractor/tests/charts/test_log_graph.py
@@ -0,0 +1,63 @@
+import numpy as np
+import matplotlib.pyplot as plt
+
+from e2b_charts import chart_figure_to_chart
+from e2b_charts.charts import LineChart
+
+
+def _prep_chart_figure():
+ # Generate x values
+ x = np.linspace(0, 100, 100)
+ # Calculate y values
+ y = np.exp(x)
+
+ # Create the plot
+ plt.figure(figsize=(10, 6))
+ plt.plot(x, y, label="y = e^x")
+
+ # Set log scale for the y-axis
+ plt.yscale("log")
+
+ # Add labels and title
+ plt.xlabel("X-axis")
+ plt.ylabel("Y-axis (log scale)")
+ plt.title("Chart with Log Scale on Y-axis")
+
+ plt.legend()
+ plt.grid(True)
+
+ return plt.gcf()
+
+
+def test_log_chart():
+ figure = _prep_chart_figure()
+ chart = chart_figure_to_chart(figure)
+ assert chart
+
+ assert isinstance(chart, LineChart)
+ assert chart.title == "Chart with Log Scale on Y-axis"
+
+ assert chart.x_label == "X-axis"
+ assert chart.y_label == "Y-axis (log scale)"
+
+ assert chart.x_unit is None
+ assert chart.y_unit == "log scale"
+
+ assert chart.x_scale == "linear"
+ assert chart.y_scale == "log"
+
+ assert all(isinstance(x, float) for x in chart.x_ticks)
+ assert all(isinstance(y, float) for y in chart.y_ticks)
+
+ assert all(isinstance(x, str) for x in chart.x_tick_labels)
+ assert all(isinstance(y, str) for y in chart.y_tick_labels)
+
+ lines = chart.elements
+ assert len(lines) == 1
+
+ line = lines[0]
+ assert line.label == "y = e^x"
+ assert len(line.points) == 100
+
+ assert all(isinstance(x, tuple) for x in line.points)
+ assert all(isinstance(x, float) and isinstance(y, float) for x, y in line.points)
diff --git a/chart_data_extractor/tests/charts/test_pie.py b/chart_data_extractor/tests/charts/test_pie.py
new file mode 100644
index 00000000..28e7ac99
--- /dev/null
+++ b/chart_data_extractor/tests/charts/test_pie.py
@@ -0,0 +1,53 @@
+import matplotlib.pyplot as plt
+
+from e2b_charts import chart_figure_to_chart
+from e2b_charts.charts import PieChart
+
+
+def _prep_chart_figure():
+ # Step 1: Define the data for the pie chart
+ categories = ["No", "No, in blue"]
+ sizes = [90, 10]
+
+ # Step 2: Create the figure and axis objects
+ fig, ax = plt.subplots(figsize=(8, 8))
+
+ plt.xlabel("x")
+ plt.ylabel("y")
+
+ # Step 3: Create the pie chart
+ ax.pie(
+ sizes,
+ labels=categories,
+ autopct="%1.1f%%",
+ startangle=90,
+ colors=plt.cm.Pastel1.colors[: len(categories)],
+ )
+
+ # Step 4: Add title and legend
+ ax.axis("equal") # Equal aspect ratio ensures that pie is drawn as a circle
+ plt.title("Will I wake up early tomorrow?")
+
+ return plt.gcf()
+
+
+def test_pie_chart():
+ figure = _prep_chart_figure()
+ chart = chart_figure_to_chart(figure)
+ assert chart
+
+ assert isinstance(chart, PieChart)
+
+ assert chart.title == "Will I wake up early tomorrow?"
+
+ assert len(chart.elements) == 2
+
+ first_data = chart.elements[0]
+ assert first_data.label == "No"
+ assert first_data.angle == 324
+ assert first_data.radius == 1
+
+ second_data = chart.elements[1]
+ assert second_data.label == "No, in blue"
+ assert second_data.angle == 36
+ assert second_data.radius == 1
diff --git a/chart_data_extractor/tests/charts/test_scatter.py b/chart_data_extractor/tests/charts/test_scatter.py
new file mode 100644
index 00000000..e57582f1
--- /dev/null
+++ b/chart_data_extractor/tests/charts/test_scatter.py
@@ -0,0 +1,58 @@
+import matplotlib.pyplot as plt
+import numpy as np
+
+from e2b_charts import chart_figure_to_chart
+from e2b_charts.charts import ScatterChart
+
+
+def _prep_chart_figure():
+ # Create data
+ N = 5
+ x1 = np.random.rand(N)
+ y1 = np.random.rand(N)
+ x2 = np.random.rand(2 * N)
+ y2 = np.random.rand(2 * N)
+
+ plt.figure(figsize=(10, 6))
+
+ plt.xlabel("A")
+ plt.ylabel("B")
+
+ plt.scatter(x1, y1, c="blue", label="Dataset 1")
+ plt.scatter(x2, y2, c="red", label="Dataset 2")
+
+ return plt.gcf()
+
+
+def test_scatter_chart():
+ figure = _prep_chart_figure()
+ chart = chart_figure_to_chart(figure)
+ assert chart
+
+ assert isinstance(chart, ScatterChart)
+
+ assert chart.title is None
+ assert chart.x_label == "A"
+ assert chart.y_label == "B"
+
+ assert chart.x_scale == "linear"
+ assert chart.y_scale == "linear"
+
+ assert all(isinstance(x, float) for x in chart.x_ticks)
+ assert all(isinstance(y, float) for y in chart.y_ticks)
+
+ assert all(isinstance(x, str) for x in chart.y_tick_labels)
+ assert all(isinstance(y, str) for y in chart.y_tick_labels)
+
+ assert len(chart.elements) == 2
+
+ first_data = chart.elements[0]
+ assert first_data.label == "Dataset 1"
+ assert len(first_data.points) == 5
+ print(first_data.points)
+ assert all(isinstance(x, tuple) for x in first_data.points)
+
+ second_data = chart.elements[1]
+ assert second_data.label == "Dataset 2"
+ assert len(second_data.points) == 10
+ assert all(isinstance(x, tuple) for x in second_data.points)
diff --git a/chart_data_extractor/tests/charts/test_supergraph.py b/chart_data_extractor/tests/charts/test_supergraph.py
new file mode 100644
index 00000000..ca3e569e
--- /dev/null
+++ b/chart_data_extractor/tests/charts/test_supergraph.py
@@ -0,0 +1,66 @@
+import matplotlib.pyplot as plt
+import numpy as np
+
+from e2b_charts import chart_figure_to_chart
+from e2b_charts.charts import (
+ ChartType,
+ LineChart,
+ ScatterChart,
+)
+from e2b_charts.main import SuperChart
+
+
+def _prep_chart_figure():
+ # Data for plotting
+ x1 = np.linspace(0, 10, 100)
+ y1 = np.sin(x1)
+
+ # Create a figure with multiple subplots
+ fig, axs = plt.subplots(1, 2, figsize=(10, 8))
+ fig.suptitle("Multiple Charts Example", fontsize=16)
+
+ # Plotting on the different axes
+ axs[0].plot(x1, y1, "r")
+ axs[0].set_title("Sine Wave")
+ axs[0].grid(True)
+
+ N = 5
+ x2 = np.random.rand(N)
+ y2 = np.random.rand(N)
+
+ axs[1].scatter(x2, y2, c="blue", label="Dataset 1")
+ axs[1].set_xlabel("X")
+ axs[1].set_ylabel("Y")
+ axs[1].set_title("Scatter Plot")
+ axs[1].grid(True)
+
+ return plt.gcf()
+
+
+def test_super_chart():
+ figure = _prep_chart_figure()
+ chart = chart_figure_to_chart(figure)
+ assert chart
+
+ assert isinstance(chart, SuperChart)
+ assert chart.type == ChartType.SUPERCHART
+ assert chart.title == "Multiple Charts Example"
+
+ charts = chart.elements
+ assert len(charts) == 2
+
+ first_chart = charts[0]
+ assert first_chart.title == "Sine Wave"
+ assert isinstance(first_chart, LineChart)
+ assert first_chart.x_label is None
+ assert first_chart.y_label is None
+ assert len(first_chart.elements) == 1
+ assert len(first_chart.elements[0].points) == 100
+
+ second_chart = charts[1]
+ assert second_chart.title == "Scatter Plot"
+ assert isinstance(second_chart, ScatterChart)
+ assert second_chart.x_label == "X"
+ assert second_chart.y_label == "Y"
+ assert len(second_chart.elements) == 1
+ assert len(second_chart.elements[0].points) == 5
diff --git a/chart_data_extractor/tests/charts/test_unknown.py b/chart_data_extractor/tests/charts/test_unknown.py
new file mode 100644
index 00000000..848afe98
--- /dev/null
+++ b/chart_data_extractor/tests/charts/test_unknown.py
@@ -0,0 +1,37 @@
+import matplotlib.pyplot as plt
+
+from e2b_charts import chart_figure_to_chart
+from e2b_charts.charts import Chart, ChartType
+
+
+def _prep_chart_figure():
+ # Create a figure and an axis
+ fig, ax = plt.subplots()
+
+ # Create data for two concentric circles
+ circle1 = plt.Circle((0, 0), 1, color="blue", fill=False, linewidth=2)
+ circle2 = plt.Circle((0, 0), 2, color="red", fill=False, linewidth=2)
+
+ # Add the circles to the axes
+ ax.add_artist(circle1)
+ ax.add_artist(circle2)
+
+ # Set grid
+ ax.grid(True)
+
+ # Set title
+ plt.title("Two Concentric Circles")
+
+ return plt.gcf()
+
+
+def test_unknown_charts():
+ figure = _prep_chart_figure()
+ chart = chart_figure_to_chart(figure)
+ assert chart
+
+ assert isinstance(chart, Chart)
+ assert chart.type == ChartType.UNKNOWN
+ assert chart.title == "Two Concentric Circles"
+
+ assert len(chart.elements) == 0
diff --git a/chart_data_extractor/tests/utils/test_detect_scale.py b/chart_data_extractor/tests/utils/test_detect_scale.py
new file mode 100644
index 00000000..62eaaa64
--- /dev/null
+++ b/chart_data_extractor/tests/utils/test_detect_scale.py
@@ -0,0 +1,24 @@
+import datetime
+
+from matplotlib.dates import _SwitchableDateConverter
+
+from e2b_charts.charts.planar import PointChart
+
+
+def test_detect_scale():
+ datetime_converter = _SwitchableDateConverter()
+ scale = PointChart._detect_scale(
+ datetime_converter, "linear", 3 * [datetime.date.today()], ["1", "2", "3"]
+ )
+ assert scale == "datetime"
+
+ scale = PointChart._detect_scale(None, "linear", [1, 2, 3], ["1", "2", "3"])
+ assert scale == "linear"
+
+ scale = PointChart._detect_scale(
+ None, "linear", [0, 1, 2], ["First", "Second", "Third"]
+ )
+ assert scale == "categorical"
+
+ scale = PointChart._detect_scale(None, "log", [1, 10, 100], ["1", "10", "100"])
+ assert scale == "log"
diff --git a/chart_data_extractor/tests/utils/test_is_grid_line.py b/chart_data_extractor/tests/utils/test_is_grid_line.py
new file mode 100644
index 00000000..02dcd2fe
--- /dev/null
+++ b/chart_data_extractor/tests/utils/test_is_grid_line.py
@@ -0,0 +1,17 @@
+from matplotlib.lines import Line2D
+
+from e2b_charts.utils.filtering import is_grid_line
+
+
+def test_is_grid_line():
+ not_a_grid_line = Line2D([1, 2], [2, 3])
+ assert not is_grid_line(not_a_grid_line)
+
+ horizontal_grid_line = Line2D([1, 2], [2, 2])
+ assert is_grid_line(horizontal_grid_line)
+
+ vertical_grid_line = Line2D([1, 1], [2, 3])
+ assert is_grid_line(vertical_grid_line)
+
+ long_line = Line2D([1, 1, 1, 1], [2, 3, 4, 5])
+ assert not is_grid_line(long_line)
diff --git a/js/.eslintrc.cjs b/js/.eslintrc.cjs
new file mode 100644
index 00000000..b572cd92
--- /dev/null
+++ b/js/.eslintrc.cjs
@@ -0,0 +1,4 @@
+module.exports = {
+ root: true,
+ extends: '../.eslintrc.cjs',
+}
diff --git a/js/.gitignore b/js/.gitignore
new file mode 100644
index 00000000..fff3a34c
--- /dev/null
+++ b/js/.gitignore
@@ -0,0 +1 @@
+deno.lock
diff --git a/js/LICENSE b/js/LICENSE
new file mode 100644
index 00000000..4aa6529d
--- /dev/null
+++ b/js/LICENSE
@@ -0,0 +1,9 @@
+MIT License
+
+Copyright (c) 2025 FOUNDRYLABS, INC.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/js/README.md b/js/README.md
index e42b464c..7ad1d4c3 100644
--- a/js/README.md
+++ b/js/README.md
@@ -1,87 +1,50 @@
-# Code interpreter extension for JavaScript
+
+
+
-The repository contains a template and modules for the code interpreter sandbox. It is based on the Jupyter server and implements the Jupyter Kernel messaging protocol. This allows for sharing context between code executions and improves support for plotting charts and other display-able data.
+
-## Key Features
+
+## What is E2B?
+[E2B](https://www.e2b.dev/) is an open-source infrastructure that allows you run to AI-generated code in secure isolated sandboxes in the cloud. To start and control sandboxes, use our [JavaScript SDK](https://www.npmjs.com/package/@e2b/code-interpreter) or [Python SDK](https://pypi.org/project/e2b_code_interpreter).
-- **Stateful Execution**: Unlike traditional sandboxes that treat each code execution independently, this package maintains context across executions.
-- **Displaying Graph & Data**: Implements parts of the [Jupyter Kernel messaging protocol](https://jupyter-client.readthedocs.io/en/latest/messaging.html), which support for interactive features like plotting charts, rendering DataFrames, etc.
+## Run your first Sandbox
-## Installation
+### 1. Install SDK
-```sh
-npm install @e2b/code-interpreter
```
-
-## Examples
-
-### Minimal example with the sharing context
-
-```js
-import { CodeInterpreter } from '@e2b/code-interpreter'
-
-const sandbox = await CodeInterpreter.create()
-await sandbox.notebook.execCell('x = 1')
-
-const execution = await sandbox.notebook.execCell('x+=1; x')
-console.log(execution.text) // outputs 2
-
-await sandbox.close()
+npm i @e2b/code-interpreter
```
-### Get charts and any display-able data
-
-```js
-import { CodeInterpreter } from '@e2b/code-interpreter'
-
-const sandbox = await CodeInterpreter.create()
-
-const code = `
-import matplotlib.pyplot as plt
-import numpy as np
-
-x = np.linspace(0, 20, 100)
-y = np.sin(x)
-
-plt.plot(x, y)
-plt.show()
-`
-
-// you can install dependencies in "jupyter notebook style"
-await sandbox.notebook.execCell("!pip install matplotlib")
-
-const execution = await sandbox.notebook.execCell(code)
-
-// this contains the image data, you can e.g. save it to file or send to frontend
-execution.results[0].png
-
-await sandbox.close()
+### 2. Get your E2B API key
+1. Sign up to E2B [here](https://e2b.dev).
+2. Get your API key [here](https://e2b.dev/dashboard?tab=keys).
+3. Set environment variable with your API key.
```
+E2B_API_KEY=e2b_***
+```
-### Streaming code output
-
-```js
-import { CodeInterpreter } from '@e2b/code-interpreter'
+### 3. Execute code with code interpreter inside Sandbox
-const code = `
-import time
-import pandas as pd
+```ts
+import { Sandbox } from '@e2b/code-interpreter'
-print("hello")
-time.sleep(3)
-data = pd.DataFrame(data=[[1, 2], [3, 4]], columns=["A", "B"])
-display(data.head(10))
-time.sleep(3)
-print("world")
-`
+const sbx = await Sandbox.create()
+await sbx.runCode('x = 1')
-const sandbox = await CodeInterpreter.create()
+const execution = await sbx.runCode('x+=1; x')
+console.log(execution.text) // outputs 2
+```
-await sandbox.notebook.execCell(code, {
- onStdout: (out) => console.log(out),
- onStderr: (outErr) => console.error(outErr),
- onResult: (result) => console.log(result.text)
-})
+### 4. Check docs
+Visit [E2B documentation](https://e2b.dev/docs).
-await sandbox.close()
-```
+### 5. E2B cookbook
+Visit our [Cookbook](https://github.com/e2b-dev/e2b-cookbook/tree/main) to get inspired by examples with different LLMs and AI frameworks.
diff --git a/js/example.js b/js/example.js
deleted file mode 100644
index 0e339030..00000000
--- a/js/example.js
+++ /dev/null
@@ -1,11 +0,0 @@
-const { CodeInterpreter } = require('./dist')
-const dotenv = require('dotenv')
-dotenv.config()
-
-async function main() {
- const sandbox = await CodeInterpreter.create()
- const r = await sandbox.notebook.execCell('x = 1; x')
- console.log(r)
-}
-
-main().catch(console.error)
diff --git a/js/example.mts b/js/example.mts
new file mode 100644
index 00000000..f96fd065
--- /dev/null
+++ b/js/example.mts
@@ -0,0 +1,35 @@
+import { config } from 'dotenv'
+
+import { Sandbox } from './dist'
+
+function log(...args: any[]) {
+ console.log(...args)
+}
+
+config()
+
+const sbx = await Sandbox.create('bwyvo5fk343pbvxst536')
+log('ℹ️ sandbox created', sbx.sandboxId)
+
+await sbx.runCode('x = 1')
+log('Sandbox code executed')
+
+const sandboxId = await sbx.betaPause()
+log('Sandbox paused', sandboxId)
+
+// Resume the sandbox from the same state
+const sameSbx = await Sandbox.connect(sbx.sandboxId)
+log('Sandbox resumed', sameSbx.sandboxId)
+
+const execution = await sameSbx.runCode('x+=1; x')
+// Output result
+log(execution.text)
+log(execution.error)
+if (execution.text !== '2') {
+ log('Test failed:', 'Failed to resume sandbox')
+ throw new Error('Failed to resume sandbox')
+}
+log('Sandbox resumed successfully')
+
+await sbx.kill()
+log('Sandbox deleted')
diff --git a/js/package.json b/js/package.json
index d9212b83..797763cf 100644
--- a/js/package.json
+++ b/js/package.json
@@ -1,6 +1,7 @@
{
"name": "@e2b/code-interpreter",
- "version": "0.0.4",
+ "version": "2.6.0",
+ "packageManager": "pnpm@9.15.9",
"description": "E2B Code Interpreter - Stateful code execution",
"homepage": "https://e2b.dev",
"license": "MIT",
@@ -29,17 +30,21 @@
"test": "vitest run",
"test:coverage": "vitest run --coverage",
"check-deps": "knip",
- "update-deps": "ncu -u && pnpm i"
+ "update-deps": "ncu -u && pnpm i",
+ "example": "npx tsx example.mts",
+ "test:bun": "bun test tests/runtimes/bun --env-file=.env",
+ "test:deno": "deno test tests/runtimes/deno/ --allow-net --allow-read --allow-env --unstable-sloppy-imports --trace-leaks",
+ "lint": "eslint src/ tests/",
+ "format": "prettier --write src/ tests/ example.mts"
},
"devDependencies": {
- "@types/node": "^18.18.6",
- "@types/ws": "^8.5.10",
+ "@types/node": "^20.19.19",
"dotenv": "^16.4.5",
- "knip": "^2.34.0",
- "npm-check-updates": "^16.14.6",
- "tsup": "^6.7.0",
- "typescript": "^5.2.2",
- "vitest": "^0.34.6"
+ "knip": "^5.25.1",
+ "npm-check-updates": "^17.1.14",
+ "tsup": "^8.5.1",
+ "typescript": "^5.5.3",
+ "vitest": "^4.1.0"
},
"files": [
"dist",
@@ -59,15 +64,13 @@
"runtime",
"vm"
],
- "dependencies": {
- "e2b": "^0.16.0",
- "isomorphic-ws": "^5.0.0",
- "ws": "^8.15.1"
- },
"engines": {
- "node": ">=18"
+ "node": ">=20"
},
"browserslist": [
"defaults"
- ]
+ ],
+ "dependencies": {
+ "e2b": "^2.28.0"
+ }
}
diff --git a/js/src/charts.ts b/js/src/charts.ts
new file mode 100644
index 00000000..d7d2a674
--- /dev/null
+++ b/js/src/charts.ts
@@ -0,0 +1,140 @@
+/**
+ * Chart types
+ */
+export enum ChartType {
+ LINE = 'line',
+ SCATTER = 'scatter',
+ BAR = 'bar',
+ PIE = 'pie',
+ BOX_AND_WHISKER = 'box_and_whisker',
+ SUPERCHART = 'superchart',
+ UNKNOWN = 'unknown',
+}
+
+/**
+ * Ax scale types
+ */
+export enum ScaleType {
+ LINEAR = 'linear',
+ DATETIME = 'datetime',
+ CATEGORICAL = 'categorical',
+ LOG = 'log',
+ SYMLOG = 'symlog',
+ LOGIT = 'logit',
+ FUNCTION = 'function',
+ FUNCTIONLOG = 'functionlog',
+ ASINH = 'asinh',
+}
+
+/**
+ * Represents a chart.
+ */
+export type Chart = {
+ type: ChartType
+ title: string
+ elements: any[]
+}
+
+type Chart2D = Chart & {
+ x_label?: string
+ y_label?: string
+ x_unit?: string
+ y_unit?: string
+}
+
+export type PointData = {
+ label: string
+ points: [number | string, number | string][]
+}
+
+type PointChart = Chart2D & {
+ x_ticks: (number | string)[]
+ x_scale: ScaleType
+ x_tick_labels: string[]
+ y_ticks: (number | string)[]
+ y_scale: ScaleType
+ y_tick_labels: string[]
+ elements: PointData[]
+}
+
+export type LineChart = PointChart & {
+ type: ChartType.LINE
+}
+
+export type ScatterChart = PointChart & {
+ type: ChartType.SCATTER
+}
+
+export type BarData = {
+ label: string
+ value: string
+ group: string
+}
+
+export type BarChart = Chart2D & {
+ type: ChartType.BAR
+ elements: BarData[]
+}
+
+export type PieData = {
+ label: string
+ angle: number
+ radius: number
+}
+
+export type PieChart = Chart & {
+ type: ChartType.PIE
+ elements: PieData[]
+}
+
+export type BoxAndWhiskerData = {
+ label: string
+ min: number
+ first_quartile: number
+ median: number
+ third_quartile: number
+ max: number
+ outliers: number[]
+}
+
+export type BoxAndWhiskerChart = Chart2D & {
+ type: ChartType.BOX_AND_WHISKER
+ elements: BoxAndWhiskerData[]
+}
+
+export type SuperChart = Chart & {
+ type: ChartType.SUPERCHART
+ elements: Chart[]
+}
+
+export type ChartTypes =
+ | LineChart
+ | ScatterChart
+ | BarChart
+ | PieChart
+ | BoxAndWhiskerChart
+ | SuperChart
+export function deserializeChart(data: any): Chart {
+ switch (data.type) {
+ case ChartType.LINE:
+ return { ...data } as LineChart
+ case ChartType.SCATTER:
+ return { ...data } as ScatterChart
+ case ChartType.BAR:
+ return { ...data } as BarChart
+ case ChartType.PIE:
+ return { ...data } as PieChart
+ case ChartType.BOX_AND_WHISKER:
+ return { ...data } as BoxAndWhiskerChart
+ case ChartType.SUPERCHART: {
+ const charts: Chart[] = data.data.map((g: any) => deserializeChart(g))
+ delete data.data
+ return {
+ ...data,
+ data: charts,
+ } as SuperChart
+ }
+ default:
+ return { ...data, type: ChartType.UNKNOWN } as Chart
+ }
+}
diff --git a/js/src/code-interpreter.ts b/js/src/code-interpreter.ts
deleted file mode 100644
index d93b9dff..00000000
--- a/js/src/code-interpreter.ts
+++ /dev/null
@@ -1,260 +0,0 @@
-import { ProcessMessage, Sandbox, SandboxOpts } from 'e2b'
-import { Result, JupyterKernelWebSocket, Execution } from './messaging'
-import { createDeferredPromise } from './utils'
-
-interface Kernels {
- [kernelID: string]: JupyterKernelWebSocket
-}
-
-export interface CreateKernelProps {
- cwd: string
- kernelName?: string
-}
-
-/**
- * E2B code interpreter sandbox extension.
- */
-export class CodeInterpreter extends Sandbox {
- private static template = 'code-interpreter-stateful'
-
- readonly notebook = new JupyterExtension(this)
-
- constructor(opts?: SandboxOpts) {
- super({ template: opts?.template || CodeInterpreter.template, ...opts })
- }
-
- override async _open(opts?: { timeout?: number }) {
- await super._open({ timeout: opts?.timeout })
- await this.notebook.connect(opts?.timeout)
-
- return this
- }
-
- override async close() {
- await this.notebook.close()
- await super.close()
- }
-}
-
-export class JupyterExtension {
- private readonly connectedKernels: Kernels = {}
-
- private readonly kernelIDPromise = createDeferredPromise()
- private readonly setDefaultKernelID = this.kernelIDPromise.resolve
-
- private get defaultKernelID() {
- return this.kernelIDPromise.promise
- }
-
- constructor(private sandbox: CodeInterpreter) {}
-
- async connect(timeout?: number) {
- return this.startConnectingToDefaultKernel(this.setDefaultKernelID, {
- timeout
- })
- }
-
- /**
- * Executes a code cell in a notebool cell.
- *
- * This method sends the provided code to a specified kernel in a remote notebook for execution.
-
- * @param code The code to be executed in the notebook cell.
- * @param kernelID The ID of the kernel to execute the code on. If not provided, the default kernel is used.
- * @param onStdout A callback function to handle standard output messages from the code execution.
- * @param onStderr A callback function to handle standard error messages from the code execution.
- * @param onResult A callback function to handle display data messages from the code execution.
- * @param timeout The maximum time to wait for the code execution to complete, in milliseconds.
- * @returns A promise that resolves with the result of the code execution.
- */
- async execCell(
- code: string,
- {
- kernelID,
- onStdout,
- onStderr,
- onResult,
- timeout
- }: {
- kernelID?: string
- onStdout?: (msg: ProcessMessage) => any
- onStderr?: (msg: ProcessMessage) => any
- onResult?: (data: Result) => any
- timeout?: number
- } = {}
- ): Promise {
- kernelID = kernelID || (await this.defaultKernelID)
- const ws =
- this.connectedKernels[kernelID] ||
- (await this.connectToKernelWS(kernelID))
-
- return await ws.sendExecutionMessage(
- code,
- onStdout,
- onStderr,
- onResult,
- timeout
- )
- }
-
- private async startConnectingToDefaultKernel(
- resolve: (value: string) => void,
- opts?: { timeout?: number }
- ) {
- const kernelID = (
- await this.sandbox.filesystem.read('/root/.jupyter/kernel_id', opts)
- ).trim()
- await this.connectToKernelWS(kernelID)
- resolve(kernelID)
- }
-
- /**
- * Connects to a kernel's WebSocket.
- *
- * This method establishes a WebSocket connection to the specified kernel. It is used internally
- * to facilitate real-time communication with the kernel, enabling operations such as executing
- * code and receiving output. The connection details are managed within the method, including
- * the retrieval of the necessary WebSocket URL from the kernel's information.
- *
- * @param kernelID The unique identifier of the kernel to connect to.
- * @throws {Error} Throws an error if the connection to the kernel's WebSocket cannot be established.
- */
- private async connectToKernelWS(kernelID: string) {
- const url = `${this.sandbox.getProtocol('ws')}://${this.sandbox.getHostname(
- 8888
- )}/api/kernels/${kernelID}/channels`
- const ws = new JupyterKernelWebSocket(url)
- await ws.connect()
- this.connectedKernels[kernelID] = ws
-
- return ws
- }
-
- /**
- * Creates a new Jupyter kernel. It can be useful if you want to have multiple independent code execution environments.
- *
- * The kernel can be optionally configured to start in a specific working directory and/or
- * with a specific kernel name. If no kernel name is provided, the default kernel will be used.
- * Once the kernel is created, this method establishes a WebSocket connection to the new kernel for
- * real-time communication.
- *
- * @param cwd Sets the current working directory where the kernel should start. Defaults to "/home/user".
- * @param kernelName The name of the kernel to create, useful if you have multiple kernel types. If not provided, the default kernel will be used.
- * @returns A promise that resolves with the ID of the newly created kernel.
- * @throws {Error} Throws an error if the kernel creation fails.
- */
- async createKernel(
- cwd: string = '/home/user',
- kernelName?: string
- ): Promise {
- const data: CreateKernelProps = { cwd }
- if (kernelName) {
- data.kernelName = kernelName
- }
-
- const response = await fetch(
- `${this.sandbox.getProtocol()}://${this.sandbox.getHostname(
- 8888
- )}/api/kernels`,
- {
- method: 'POST',
- body: JSON.stringify(data)
- }
- )
-
- if (!response.ok) {
- throw new Error(`Failed to create kernel: ${response.statusText}`)
- }
-
- const kernelID = (await response.json()).id
- await this.connectToKernelWS(kernelID)
- return kernelID
- }
-
- /**
- * Restarts an existing Jupyter kernel. This can be useful to reset the kernel's state or to recover from errors.
- *
- * @param kernelID The unique identifier of the kernel to restart. If not provided, the default kernel is restarted.
- * @throws {Error} Throws an error if the kernel restart fails or if the operation times out.
- */
- async restartKernel(kernelID?: string) {
- kernelID = kernelID || (await this.defaultKernelID)
- this.connectedKernels[kernelID].close()
- delete this.connectedKernels[kernelID]
-
- const response = await fetch(
- `${this.sandbox.getProtocol()}://${this.sandbox.getHostname(
- 8888
- )}/api/kernels/${kernelID}/restart`,
- {
- method: 'POST'
- }
- )
-
- if (!response.ok) {
- throw new Error(`Failed to restart kernel ${kernelID}`)
- }
-
- await this.connectToKernelWS(kernelID)
- }
-
- /**
- * Shuts down an existing Jupyter kernel. This method is used to gracefully terminate a kernel's process.
-
- * @param kernelID The unique identifier of the kernel to shutdown. If not provided, the default kernel is shutdown.
- * @throws {Error} Throws an error if the kernel shutdown fails or if the operation times out.
- */
- async shutdownKernel(kernelID?: string) {
- kernelID = kernelID || (await this.defaultKernelID)
- this.connectedKernels[kernelID].close()
- delete this.connectedKernels[kernelID]
-
- const response = await fetch(
- `${this.sandbox.getProtocol()}://${this.sandbox.getHostname(
- 8888
- )}/api/kernels/${kernelID}`,
- {
- method: 'DELETE'
- }
- )
-
- if (!response.ok) {
- throw new Error(`Failed to shutdown kernel ${kernelID}`)
- }
- }
-
- /**
- * Lists all available Jupyter kernels.
- *
- * This method fetches a list of all currently available Jupyter kernels from the server. It can be used
- * to retrieve the IDs of all kernels that are currently running or available for connection.
- *
- * @returns A promise that resolves to an array of kernel IDs.
- * @throws {Error} Throws an error if the request to list kernels fails.
- */
- async listKernels(): Promise {
- const response = await fetch(
- `${this.sandbox.getProtocol()}://${this.sandbox.getHostname(
- 8888
- )}/api/kernels`,
- {
- method: 'GET'
- }
- )
-
- if (!response.ok) {
- throw new Error(`Failed to list kernels: ${response.statusText}`)
- }
-
- return (await response.json()).map((kernel: { id: string }) => kernel.id)
- }
-
- /**
- * Close all the websocket connections to the kernels. It doesn't shutdown the kernels.
- */
- async close() {
- for (const kernelID of Object.keys(this.connectedKernels)) {
- this.connectedKernels[kernelID].close()
- }
- }
-}
diff --git a/js/src/consts.ts b/js/src/consts.ts
new file mode 100644
index 00000000..535ded60
--- /dev/null
+++ b/js/src/consts.ts
@@ -0,0 +1,2 @@
+export const DEFAULT_TIMEOUT_MS = 60_000 // 1 minute
+export const JUPYTER_PORT = 49999
diff --git a/js/src/index.ts b/js/src/index.ts
index 87b07d0f..d4598121 100644
--- a/js/src/index.ts
+++ b/js/src/index.ts
@@ -1,10 +1,37 @@
-export { CodeInterpreter, JupyterExtension } from './code-interpreter'
-export type { CreateKernelProps } from './code-interpreter'
-
-export type { Logs, ExecutionError, Result, Execution, MIMEType, RawData } from './messaging'
-
-import { CodeInterpreter } from './code-interpreter'
-
export * from 'e2b'
-export default CodeInterpreter
\ No newline at end of file
+export { Sandbox } from './sandbox'
+export type {
+ Context,
+ RunCodeLanguage,
+ RunCodeOpts,
+ CreateCodeContextOpts,
+} from './sandbox'
+export type {
+ Logs,
+ ExecutionError,
+ Result,
+ Execution,
+ MIMEType,
+ RawData,
+ OutputMessage,
+} from './messaging'
+export type {
+ ScaleType,
+ ChartType,
+ ChartTypes,
+ Chart,
+ BarChart,
+ BarData,
+ LineChart,
+ ScatterChart,
+ BoxAndWhiskerChart,
+ BoxAndWhiskerData,
+ PieChart,
+ PieData,
+ SuperChart,
+ PointData,
+} from './charts'
+import { Sandbox } from './sandbox'
+
+export default Sandbox
diff --git a/js/src/messaging.ts b/js/src/messaging.ts
index fbe9b8b4..5f1e4e2c 100644
--- a/js/src/messaging.ts
+++ b/js/src/messaging.ts
@@ -1,6 +1,46 @@
-import IWebSocket from 'isomorphic-ws'
-import { ProcessMessage } from 'e2b'
-import { id } from './utils'
+import { NotFoundError, SandboxError, TimeoutError } from 'e2b'
+import { ChartTypes } from './charts'
+
+export async function extractError(res: Response) {
+ if (res.ok) {
+ return
+ }
+
+ switch (res.status) {
+ case 502:
+ return new TimeoutError(
+ `${await res.text()}: This error is likely due to sandbox timeout. You can modify the sandbox timeout by passing 'timeoutMs' when starting the sandbox or calling '.setTimeout' on the sandbox with the desired timeout.`
+ )
+ case 404:
+ return new NotFoundError(await res.text())
+ default:
+ return new SandboxError(`${res.status} ${res.statusText}`)
+ }
+}
+
+/**
+ * Represents an output message from the sandbox code execution.
+ */
+export class OutputMessage {
+ constructor(
+ /**
+ * The output line.
+ */
+ public readonly line: string,
+ /**
+ * Unix epoch in nanoseconds.
+ */
+ public readonly timestamp: number,
+ /**
+ * Whether the output is an error.
+ */
+ public readonly error: boolean
+ ) {}
+
+ public toString() {
+ return this.line
+ }
+}
/**
* Represents an error that occurred during the execution of a cell.
@@ -19,15 +59,8 @@ export class ExecutionError {
/**
* The raw traceback of the error.
**/
- public tracebackRaw: string[]
- ) { }
-
- /**
- * Returns the traceback of the error as a string.
- */
- get traceback(): string {
- return this.tracebackRaw.join('\n')
- }
+ public traceback: string
+ ) {}
}
/**
@@ -35,12 +68,17 @@ export class ExecutionError {
*/
export type MIMEType = string
+type E2BData = {
+ data: Record
+ chart: ChartTypes
+}
+
/**
- * Dictionary that maps MIME types to their corresponding string representations of the data.
+ * Dictionary that maps MIME types to their corresponding representations of the data.
*/
export type RawData = {
[key: MIMEType]: string
-}
+} & E2BData
/**
* Represents the data to be displayed as a result of executing a cell in a Jupyter notebook.
@@ -92,6 +130,14 @@ export class Result {
* JavaScript representation of the data.
*/
readonly javascript?: string
+ /**
+ * Contains the data from DataFrame.
+ */
+ readonly data?: Record
+ /**
+ * Contains the chart data.
+ */
+ readonly chart?: ChartTypes
/**
* Extra data that can be included. Not part of the standard types.
*/
@@ -99,34 +145,49 @@ export class Result {
readonly raw: RawData
- constructor(data: RawData, public readonly isMainResult: boolean) {
- this.text = data['text/plain']
- this.html = data['text/html']
- this.markdown = data['text/markdown']
- this.svg = data['image/svg+xml']
- this.png = data['image/png']
- this.jpeg = data['image/jpeg']
- this.pdf = data['application/pdf']
- this.latex = data['text/latex']
- this.json = data['application/json']
- this.javascript = data['application/javascript']
+ constructor(
+ rawData: RawData,
+ public readonly isMainResult: boolean
+ ) {
+ const data = { ...rawData }
+ delete data['type']
+ delete data['is_main_result']
+
+ this.text = data['text']
+ this.html = data['html']
+ this.markdown = data['markdown']
+ this.svg = data['svg']
+ this.png = data['png']
+ this.jpeg = data['jpeg']
+ this.pdf = data['pdf']
+ this.latex = data['latex']
+ this.json = data['json']
+ this.javascript = data['javascript']
this.isMainResult = isMainResult
this.raw = data
+ this.data = data['data']
+ this.chart = data['chart']
+
this.extra = {}
+
for (const key of Object.keys(data)) {
if (
![
- 'text/plain',
- 'text/html',
- 'text/markdown',
- 'image/svg+xml',
- 'image/png',
- 'image/jpeg',
- 'application/pdf',
- 'text/latex',
- 'application/json',
- 'application/javascript'
+ 'plain',
+ 'html',
+ 'markdown',
+ 'svg',
+ 'png',
+ 'jpeg',
+ 'pdf',
+ 'latex',
+ 'json',
+ 'javascript',
+ 'data',
+ 'chart',
+ 'extra',
+ 'text',
].includes(key)
) {
this.extra[key] = data[key]
@@ -168,6 +229,9 @@ export class Result {
if (this.javascript) {
formats.push('javascript')
}
+ if (this.data) {
+ formats.push('data')
+ }
for (const key of Object.keys(this.extra)) {
formats.push(key)
@@ -191,7 +255,7 @@ export class Result {
latex: this.latex,
json: this.json,
javascript: this.javascript,
- ...(Object.keys(this.extra).length > 0 ? { extra: this.extra } : {})
+ ...(Object.keys(this.extra).length > 0 ? { extra: this.extra } : {}),
}
}
}
@@ -218,16 +282,20 @@ export class Execution {
/**
* List of result of the cell (interactively interpreted last line), display calls (e.g. matplotlib plots).
*/
- public results: Result[],
+ public results: Result[] = [],
/**
* Logs printed to stdout and stderr during execution.
*/
- public logs: Logs,
+ public logs: Logs = { stdout: [], stderr: [] },
/**
* An Error object if an error occurred, null otherwise.
*/
- public error?: ExecutionError
- ) { }
+ public error?: ExecutionError,
+ /**
+ * Execution count of the cell.
+ */
+ public executionCount?: number
+ ) {}
/**
* Returns the text representation of the main result of the cell.
@@ -247,270 +315,61 @@ export class Execution {
return {
results: this.results,
logs: this.logs,
- error: this.error
+ error: this.error,
}
}
}
-/**
- * Represents the execution of a cell in the Jupyter kernel.
- * It's an internal class used by JupyterKernelWebSocket.
- */
-class CellExecution {
- execution: Execution
- onStdout?: (out: ProcessMessage) => any
- onStderr?: (out: ProcessMessage) => any
- onResult?: (data: Result) => any
- inputAccepted: boolean = false
-
- constructor(
- onStdout?: (out: ProcessMessage) => any,
- onStderr?: (out: ProcessMessage) => any,
- onResult?: (data: Result) => any
- ) {
- this.execution = new Execution([], { stdout: [], stderr: [] })
- this.onStdout = onStdout
- this.onStderr = onStderr
- this.onResult = onResult
- }
-}
-
-interface Cells {
- [id: string]: CellExecution
-}
-
-export class JupyterKernelWebSocket {
- // native websocket
- private _ws?: IWebSocket
-
- private set ws(ws: IWebSocket) {
- this._ws = ws
- }
-
- private get ws() {
- if (!this._ws) {
- throw new Error('WebSocket is not connected.')
- }
- return this._ws
- }
-
- private idAwaiter: {
- [id: string]: (data?: any) => void
- } = {}
-
- private cells: Cells = {}
-
- // constructor
- /**
- * Does not start WebSocket connection!
- * You need to call connect() method first.
- */
- constructor(private readonly url: string) { }
-
- // public
- /**
- * Starts WebSocket connection.
- */
- connect() {
- this._ws = new IWebSocket(this.url)
- return this.listen()
- }
-
- // events
- /**
- * Listens for messages from WebSocket server.
- *
- * Message types:
- * https://jupyter-client.readthedocs.io/en/stable/messaging.html
- *
- */
- public listenMessages() {
- this.ws.onmessage = (e: IWebSocket.MessageEvent) => {
- const message = JSON.parse(e.data.toString())
- const parentMsgId = message.parent_header.msg_id
- const cell = this.cells[parentMsgId]
- if (!cell) {
- return
- }
-
- const execution = cell.execution
- if (message.msg_type == 'error') {
- execution.error = new ExecutionError(
- message.content.ename,
- message.content.evalue,
- message.content.traceback
- )
- } else if (message.msg_type == 'stream') {
- if (message.content.name == 'stdout') {
- execution.logs.stdout.push(message.content.text)
- if (cell?.onStdout) {
- cell.onStdout(
- new ProcessMessage(
- message.content.text,
- new Date().getTime() * 1_000_000,
- false
- )
- )
- }
- } else if (message.content.name == 'stderr') {
- execution.logs.stderr.push(message.content.text)
- if (cell?.onStderr) {
- cell.onStderr(
- new ProcessMessage(
- message.content.text,
- new Date().getTime() * 1_000_000,
- true
- )
- )
- }
- }
- } else if (message.msg_type == 'display_data') {
- const result = new Result(message.content.data, false)
- execution.results.push(result)
- if (cell.onResult) {
- cell.onResult(result)
- }
- } else if (message.msg_type == 'execute_result') {
- const result = new Result(message.content.data, true)
- execution.results.push(result)
- if (cell.onResult) {
- cell.onResult(result)
- }
- } else if (message.msg_type == 'status') {
- if (message.content.execution_state == 'idle') {
- if (cell.inputAccepted) {
- this.idAwaiter[parentMsgId](execution)
- }
- } else if (message.content.execution_state == 'error') {
- execution.error = new ExecutionError(
- message.content.ename,
- message.content.evalue,
- message.content.traceback
- )
- this.idAwaiter[parentMsgId](execution)
- }
- } else if (message.msg_type == 'execute_reply') {
- if (message.content.status == 'error') {
- execution.error = new ExecutionError(
- message.content.ename,
- message.content.evalue,
- message.content.traceback
- )
- } else if (message.content.status == 'ok') {
- return
- }
- } else if (message.msg_type == 'execute_input') {
- cell.inputAccepted = true
- } else {
- console.warn('[UNHANDLED MESSAGE TYPE]:', message.msg_type)
+export async function parseOutput(
+ execution: Execution,
+ line: string,
+ onStdout?: (output: OutputMessage) => Promise | any,
+ onStderr?: (output: OutputMessage) => Promise | any,
+ onResult?: (data: Result) => Promise | any,
+ onError?: (error: ExecutionError) => Promise | any
+) {
+ const msg = JSON.parse(line)
+
+ switch (msg.type) {
+ case 'result': {
+ const result = new Result(
+ { ...msg, type: undefined, is_main_result: undefined },
+ msg.is_main_result
+ )
+ execution.results.push(result)
+ if (onResult) {
+ await onResult(result)
}
+ break
}
- }
-
- // communication
- /**
- * Sends code to be executed by Jupyter kernel.
- * @param code Code to be executed.
- * @param onStdout Callback for stdout messages.
- * @param onStderr Callback for stderr messages.
- * @param onResult Callback function to handle the result and display calls of the code execution.
- * @param timeout Time in milliseconds to wait for response.
- * @returns Promise with execution result.
- */
- public sendExecutionMessage(
- code: string,
- onStdout?: (out: ProcessMessage) => any,
- onStderr?: (out: ProcessMessage) => any,
- onResult?: (data: Result) => any,
- timeout?: number
- ) {
- return new Promise((resolve, reject) => {
- const msg_id = id(16)
- const data = this.sendExecuteRequest(msg_id, code)
-
- // give limited time for response
- let timeoutSet: number | NodeJS.Timeout
- if (timeout) {
- timeoutSet = setTimeout(() => {
- // stop waiting for response
- delete this.idAwaiter[msg_id]
- reject(
- new Error(
- `Awaiting response to "${code}" with id: ${msg_id} timed out.`
- )
- )
- }, timeout)
- }
-
- // expect response
- this.cells[msg_id] = new CellExecution(onStdout, onStderr, onResult)
- this.idAwaiter[msg_id] = (responseData: Execution) => {
- // stop timeout
- clearInterval(timeoutSet as number)
- // stop waiting for response
- delete this.idAwaiter[msg_id]
-
- resolve(responseData)
+ case 'stdout':
+ execution.logs.stdout.push(msg.text)
+ if (onStdout) {
+ await onStdout({
+ error: false,
+ line: msg.text,
+ timestamp: new Date().getTime() * 1000,
+ })
}
-
- const json = JSON.stringify(data)
- this.ws.send(json)
- })
- }
-
- /**
- * Listens for messages from WebSocket server.
- */
- private listen() {
- return new Promise((resolve, reject) => {
- this.ws.onopen = (e: unknown) => {
- resolve(e)
+ break
+ case 'stderr':
+ execution.logs.stderr.push(msg.text)
+ if (onStderr) {
+ await onStderr({
+ error: true,
+ line: msg.text,
+ timestamp: new Date().getTime() * 1000,
+ })
}
-
- // listen for messages
- this.listenMessages()
-
- this.ws.onclose = (e: IWebSocket.CloseEvent) => {
- reject(
- new Error(
- `WebSocket closed with code: ${e.code} and reason: ${e.reason}`
- )
- )
+ break
+ case 'error':
+ execution.error = new ExecutionError(msg.name, msg.value, msg.traceback)
+ if (onError) {
+ await onError(execution.error)
}
- })
- }
-
- /**
- * Creates a websocket message for code execution.
- * @param msg_id Unique message id.
- * @param code Code to be executed.
- */
- private sendExecuteRequest(msg_id: string, code: string) {
- const session = id(16)
- return {
- header: {
- msg_id: msg_id,
- username: 'e2b',
- session: session,
- msg_type: 'execute_request',
- version: '5.3'
- },
- parent_header: {},
- metadata: {},
- content: {
- code: code,
- silent: false,
- store_history: false,
- user_expressions: {},
- allow_stdin: false
- }
- }
- }
-
- /**
- * Closes WebSocket connection.
- */
- close() {
- this.ws.close()
+ break
+ case 'number_of_executions':
+ execution.executionCount = msg.execution_count
+ break
}
}
diff --git a/js/src/sandbox.ts b/js/src/sandbox.ts
new file mode 100644
index 00000000..0b320cc6
--- /dev/null
+++ b/js/src/sandbox.ts
@@ -0,0 +1,430 @@
+import { Sandbox as BaseSandbox, InvalidArgumentError } from 'e2b'
+
+import {
+ Result,
+ Execution,
+ OutputMessage,
+ parseOutput,
+ extractError,
+ ExecutionError,
+} from './messaging'
+import {
+ formatExecutionTimeoutError,
+ formatRequestTimeoutError,
+ readLines,
+} from './utils'
+import { JUPYTER_PORT, DEFAULT_TIMEOUT_MS } from './consts'
+
+/**
+ * Represents a context for code execution.
+ */
+export type Context = {
+ /**
+ * The ID of the context.
+ */
+ id: string
+ /**
+ * The language of the context.
+ */
+ language: string
+ /**
+ * The working directory of the context.
+ */
+ cwd: string
+}
+
+/* eslint-disable @typescript-eslint/ban-types */
+/**
+ * Supported language for code execution.
+ */
+export type RunCodeLanguage =
+ | 'python'
+ | 'javascript'
+ | 'typescript'
+ | 'r'
+ | 'java'
+ | 'bash'
+ | (string & {})
+/* eslint-enable @typescript-eslint/ban-types */
+
+/**
+ * Options for running code.
+ */
+export interface RunCodeOpts {
+ /**
+ * Callback for handling stdout messages.
+ */
+ onStdout?: (output: OutputMessage) => Promise | any
+ /**
+ * Callback for handling stderr messages.
+ */
+ onStderr?: (output: OutputMessage) => Promise | any
+ /**
+ * Callback for handling the final execution result.
+ */
+ onResult?: (data: Result) => Promise | any
+ /**
+ * Callback for handling the `ExecutionError` object.
+ */
+ onError?: (error: ExecutionError) => Promise | any
+ /**
+ * Custom environment variables for code execution.
+ *
+ * @default {}
+ */
+ envs?: Record
+ /**
+ * Timeout for the code execution in **milliseconds**.
+ *
+ * @default 60_000 // 60 seconds
+ */
+ timeoutMs?: number
+ /**
+ * Timeout for the request in **milliseconds**.
+ *
+ * @default 30_000 // 30 seconds
+ */
+ requestTimeoutMs?: number
+}
+
+/**
+ * Options for creating a code context.
+ */
+export interface CreateCodeContextOpts {
+ /**
+ * Working directory for the context.
+ *
+ * @default /home/user
+ */
+ cwd?: string
+ /**
+ * Language for the context.
+ *
+ * @default python
+ */
+ language?: RunCodeLanguage
+ /**
+ * Timeout for the request in **milliseconds**.
+ *
+ * @default 30_000 // 30 seconds
+ */
+ requestTimeoutMs?: number
+}
+
+/**
+ * E2B cloud sandbox is a secure and isolated cloud environment.
+ *
+ * The sandbox allows you to:
+ * - Access Linux OS
+ * - Create, list, and delete files and directories
+ * - Run commands
+ * - Run isolated code
+ * - Access the internet
+ *
+ * Check docs [here](https://e2b.dev/docs).
+ *
+ * Use {@link Sandbox.create} to create a new sandbox.
+ *
+ * @example
+ * ```ts
+ * import { Sandbox } from '@e2b/code-interpreter'
+ *
+ * const sandbox = await Sandbox.create()
+ * ```
+ */
+export class Sandbox extends BaseSandbox {
+ protected static override readonly defaultTemplate: string =
+ 'code-interpreter-v1'
+
+ protected get jupyterUrl(): string {
+ return `${this.connectionConfig.debug ? 'http' : 'https'}://${this.getHost(
+ JUPYTER_PORT
+ )}`
+ }
+
+ /**
+ * Run the code for the specified language.
+ *
+ * Specify the `language` or `context` option to run the code as a different language or in a different `Context`.
+ * If no language is specified, Python is used.
+ *
+ * You can reference previously defined variables, imports, and functions in the code.
+ *
+ * @param code code to execute.
+ * @param opts options for executing the code.
+ *
+ * @returns `Execution` result object.
+ */
+ async runCode(
+ code: string,
+ opts?: RunCodeOpts & {
+ /**
+ * Language to use for code execution.
+ *
+ * If not defined, the default Python context is used.
+ */
+ language?: RunCodeLanguage
+ }
+ ): Promise
+ /**
+ * Runs the code in the specified context, if not specified, the default context is used.
+ *
+ * Specify the `language` or `context` option to run the code as a different language or in a different `Context`.
+ *
+ * You can reference previously defined variables, imports, and functions in the code.
+ *
+ * @param code code to execute.
+ * @param opts options for executing the code
+ *
+ * @returns `Execution` result object
+ */
+ async runCode(
+ code: string,
+ opts?: RunCodeOpts & {
+ /**
+ * Context to run the code in.
+ */
+ context?: Context
+ }
+ ): Promise
+ async runCode(
+ code: string,
+ opts?: RunCodeOpts & {
+ language?: string
+ context?: Context
+ }
+ ): Promise {
+ if (opts?.context && opts?.language) {
+ throw new InvalidArgumentError(
+ 'You can provide context or language, but not both at the same time.'
+ )
+ }
+
+ const controller = new AbortController()
+
+ const requestTimeout =
+ opts?.requestTimeoutMs ?? this.connectionConfig.requestTimeoutMs
+
+ const reqTimer = requestTimeout
+ ? setTimeout(() => {
+ controller.abort()
+ }, requestTimeout)
+ : undefined
+
+ const headers: Record = {
+ 'Content-Type': 'application/json',
+ }
+
+ if (this.trafficAccessToken) {
+ headers['E2B-Traffic-Access-Token'] = this.trafficAccessToken
+ }
+ if (this.envdAccessToken) {
+ headers['X-Access-Token'] = this.envdAccessToken
+ }
+
+ try {
+ const res = await fetch(`${this.jupyterUrl}/execute`, {
+ method: 'POST',
+ headers,
+ body: JSON.stringify({
+ code,
+ context_id: opts?.context?.id,
+ language: opts?.language,
+ env_vars: opts?.envs,
+ }),
+ signal: controller.signal,
+ keepalive: true,
+ })
+
+ const error = await extractError(res)
+ if (error) {
+ throw error
+ }
+
+ if (!res.body) {
+ throw new Error(
+ `Not response body: ${res.statusText} ${await res?.text()}`
+ )
+ }
+
+ clearTimeout(reqTimer)
+
+ const bodyTimeout = opts?.timeoutMs ?? DEFAULT_TIMEOUT_MS
+
+ const bodyTimer = bodyTimeout
+ ? setTimeout(() => {
+ controller.abort()
+ }, bodyTimeout)
+ : undefined
+
+ const execution = new Execution()
+
+ try {
+ for await (const chunk of readLines(res.body)) {
+ await parseOutput(
+ execution,
+ chunk,
+ opts?.onStdout,
+ opts?.onStderr,
+ opts?.onResult,
+ opts?.onError
+ )
+ }
+ } catch (error) {
+ throw formatExecutionTimeoutError(error)
+ } finally {
+ clearTimeout(bodyTimer)
+ }
+
+ return execution
+ } catch (error) {
+ throw formatRequestTimeoutError(error)
+ }
+ }
+
+ /**
+ * Creates a new context to run code in.
+ *
+ * @param opts options for creating the context.
+ *
+ * @returns context object.
+ */
+ async createCodeContext(opts?: CreateCodeContextOpts): Promise {
+ try {
+ const headers: Record = {
+ 'Content-Type': 'application/json',
+ }
+
+ if (this.trafficAccessToken) {
+ headers['E2B-Traffic-Access-Token'] = this.trafficAccessToken
+ }
+
+ const res = await fetch(`${this.jupyterUrl}/contexts`, {
+ method: 'POST',
+ headers,
+ body: JSON.stringify({
+ language: opts?.language,
+ cwd: opts?.cwd,
+ }),
+ keepalive: true,
+ signal: this.connectionConfig.getSignal(opts?.requestTimeoutMs),
+ })
+
+ const error = await extractError(res)
+ if (error) {
+ throw error
+ }
+
+ return await res.json()
+ } catch (error) {
+ throw formatRequestTimeoutError(error)
+ }
+ }
+
+ /**
+ * Removes a context.
+ *
+ * @param context context to remove.
+ *
+ * @returns void.
+ */
+ async removeCodeContext(context: Context | string): Promise {
+ try {
+ const id = typeof context === 'string' ? context : context.id
+ const headers: Record = {
+ 'Content-Type': 'application/json',
+ }
+
+ if (this.trafficAccessToken) {
+ headers['E2B-Traffic-Access-Token'] = this.trafficAccessToken
+ }
+
+ const res = await fetch(`${this.jupyterUrl}/contexts/${id}`, {
+ method: 'DELETE',
+ headers,
+ keepalive: true,
+ signal: this.connectionConfig.getSignal(
+ this.connectionConfig.requestTimeoutMs
+ ),
+ })
+
+ const error = await extractError(res)
+ if (error) {
+ throw error
+ }
+ } catch (error) {
+ throw formatRequestTimeoutError(error)
+ }
+ }
+
+ /**
+ * List all contexts.
+ *
+ * @returns list of contexts.
+ */
+ async listCodeContexts(): Promise {
+ try {
+ const headers: Record = {
+ 'Content-Type': 'application/json',
+ }
+
+ if (this.trafficAccessToken) {
+ headers['E2B-Traffic-Access-Token'] = this.trafficAccessToken
+ }
+
+ const res = await fetch(`${this.jupyterUrl}/contexts`, {
+ method: 'GET',
+ headers,
+ keepalive: true,
+ signal: this.connectionConfig.getSignal(
+ this.connectionConfig.requestTimeoutMs
+ ),
+ })
+
+ const error = await extractError(res)
+ if (error) {
+ throw error
+ }
+
+ return await res.json()
+ } catch (error) {
+ throw formatRequestTimeoutError(error)
+ }
+ }
+
+ /**
+ * Restart a context.
+ *
+ * @param context context to restart.
+ *
+ * @returns void.
+ */
+ async restartCodeContext(context: Context | string): Promise {
+ try {
+ const id = typeof context === 'string' ? context : context.id
+ const headers: Record = {
+ 'Content-Type': 'application/json',
+ }
+
+ if (this.trafficAccessToken) {
+ headers['E2B-Traffic-Access-Token'] = this.trafficAccessToken
+ }
+
+ const res = await fetch(`${this.jupyterUrl}/contexts/${id}/restart`, {
+ method: 'POST',
+ headers,
+ keepalive: true,
+ signal: this.connectionConfig.getSignal(
+ this.connectionConfig.requestTimeoutMs
+ ),
+ })
+
+ const error = await extractError(res)
+ if (error) {
+ throw error
+ }
+ } catch (error) {
+ throw formatRequestTimeoutError(error)
+ }
+ }
+}
diff --git a/js/src/utils.ts b/js/src/utils.ts
index 33a7982d..0bf73c3c 100644
--- a/js/src/utils.ts
+++ b/js/src/utils.ts
@@ -1,27 +1,55 @@
-export function createDeferredPromise() {
- let resolve: (value: T) => void
- let reject: (reason?: unknown) => void
- const promise = new Promise((res, rej) => {
- resolve = res
- reject = rej
- })
-
- return {
- promise,
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- reject: reject!,
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
- resolve: resolve!
+import { TimeoutError } from 'e2b'
+
+export function formatRequestTimeoutError(error: unknown) {
+ if (error instanceof Error && error.name === 'AbortError') {
+ return new TimeoutError(
+ "Request timed out — the 'requestTimeoutMs' option can be used to increase this timeout"
+ )
+ }
+
+ return error
+}
+
+export function formatExecutionTimeoutError(error: unknown) {
+ if (error instanceof Error && error.name === 'AbortError') {
+ return new TimeoutError(
+ "Execution timed out — the 'timeoutMs' option can be used to increase this timeout"
+ )
}
+
+ return error
}
-export function id(length: number) {
- let result = ''
- const characters =
- 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
- const charactersLength = characters.length
- for (let i = 0; i < length; i++) {
- result += characters.charAt(Math.floor(Math.random() * charactersLength))
+export async function* readLines(stream: ReadableStream) {
+ const reader = stream.getReader()
+ let buffer = ''
+
+ try {
+ while (true) {
+ const { done, value } = await reader.read()
+
+ if (value !== undefined) {
+ buffer += new TextDecoder().decode(value)
+ }
+
+ if (done) {
+ if (buffer.length > 0) {
+ yield buffer
+ }
+ break
+ }
+
+ let newlineIdx = -1
+
+ do {
+ newlineIdx = buffer.indexOf('\n')
+ if (newlineIdx !== -1) {
+ yield buffer.slice(0, newlineIdx)
+ buffer = buffer.slice(newlineIdx + 1)
+ }
+ } while (newlineIdx !== -1)
+ }
+ } finally {
+ reader.releaseLock()
}
- return result
}
diff --git a/js/tests/bash.test.ts b/js/tests/bash.test.ts
index 5a2f07cd..7734499f 100644
--- a/js/tests/bash.test.ts
+++ b/js/tests/bash.test.ts
@@ -1,13 +1,10 @@
-import { CodeInterpreter } from '../src'
+import { expect } from 'vitest'
-import { expect, test } from 'vitest'
+import { isDebug, sandboxTest } from './setup'
-test('bash', async () => {
- const sandbox = await CodeInterpreter.create()
-
- const result = await sandbox.notebook.execCell('!pwd')
+// Skip this test if we are running in debug mode — the pwd and user in the testing docker container are not the same as in the actual sandbox.
+sandboxTest.skipIf(isDebug)('bash', async ({ sandbox }) => {
+ const result = await sandbox.runCode('!pwd')
expect(result.logs.stdout.join().trim()).toEqual('/home/user')
-
- await sandbox.close()
})
diff --git a/js/tests/basic.test.ts b/js/tests/basic.test.ts
index 90a0110f..2f0b9837 100644
--- a/js/tests/basic.test.ts
+++ b/js/tests/basic.test.ts
@@ -1,13 +1,14 @@
-import { CodeInterpreter } from '../src'
+import { expect } from 'vitest'
+import { isDebug, sandboxTest, secureSandboxTest } from './setup'
-import { expect, test } from 'vitest'
+sandboxTest('basic', async ({ sandbox }) => {
+ const result = await sandbox.runCode('x =1; x')
-test('basic', async () => {
- const sandbox = await CodeInterpreter.create()
+ expect(result.text).toEqual('1')
+})
- const result = await sandbox.notebook.execCell('x =1; x')
+secureSandboxTest.skipIf(isDebug)('secure access', async ({ sandbox }) => {
+ const result = await sandbox.runCode('x =1; x')
expect(result.text).toEqual('1')
-
- await sandbox.close()
})
diff --git a/js/tests/benchmarking.js b/js/tests/benchmarking.js
deleted file mode 100644
index 703656b0..00000000
--- a/js/tests/benchmarking.js
+++ /dev/null
@@ -1,31 +0,0 @@
-const { CodeInterpreter } = require('../dist')
-const dotenv = require('dotenv')
-dotenv.config()
-
-const iterations = 10
-let createSandboxTime = 0
-let fistExecTime = 0
-let secondExecTime = 0
-
-async function main() {
- for (let i = 0; i < iterations; i++) {
- console.log('Iteration:', i + 1)
- let startTime = new Date()
- const sandbox = await CodeInterpreter.create()
- createSandboxTime += new Date() - startTime
-
- startTime = new Date()
- await sandbox.notebook.execCell('x = 1')
- fistExecTime += new Date() - startTime
-
- startTime = new Date()
- const result = await sandbox.notebook.execCell('x+=1; x')
- secondExecTime += new Date() - startTime
-
- await sandbox.close()
- }
- console.log('Average create sandbox time:', createSandboxTime / iterations)
- console.log('Average first exec time:', fistExecTime / iterations)
- console.log('Average second exec time:', secondExecTime / iterations)
-}
-main().catch(console.error)
diff --git a/js/tests/callbacks.test.ts b/js/tests/callbacks.test.ts
new file mode 100644
index 00000000..abc109ad
--- /dev/null
+++ b/js/tests/callbacks.test.ts
@@ -0,0 +1,46 @@
+import { expect } from 'vitest'
+
+import { sandboxTest } from './setup'
+
+sandboxTest('callback results', async ({ sandbox }) => {
+ const results = []
+ const result = await sandbox.runCode('x =1; x', {
+ onResult: (result) => results.push(result),
+ })
+
+ expect(results.length).toBe(1)
+ expect(result.results[0].text).toBe('1')
+})
+
+sandboxTest('callback error', async ({ sandbox }) => {
+ const errors = []
+ const result = await sandbox.runCode('xyz', {
+ onError: (error) => errors.push(error),
+ })
+
+ expect(errors.length).toBe(1)
+ expect(result.error.name).toBe('NameError')
+})
+
+sandboxTest('callback stdout', async ({ sandbox }) => {
+ const stdout = []
+ const result = await sandbox.runCode('print("hello")', {
+ onStdout: (out) => stdout.push(out),
+ })
+
+ expect(stdout.length).toBe(1)
+ expect(result.logs.stdout).toEqual(['hello\n'])
+})
+
+sandboxTest('callback stderr', async ({ sandbox }) => {
+ const stderr = []
+ const result = await sandbox.runCode(
+ 'import sys;print("This is an error message", file=sys.stderr)',
+ {
+ onStderr: (err) => stderr.push(err),
+ }
+ )
+
+ expect(stderr.length).toBe(1)
+ expect(result.logs.stderr).toEqual(['This is an error message\n'])
+})
diff --git a/js/tests/charts/bar.test.ts b/js/tests/charts/bar.test.ts
new file mode 100644
index 00000000..01a2b055
--- /dev/null
+++ b/js/tests/charts/bar.test.ts
@@ -0,0 +1,54 @@
+import { expect } from 'vitest'
+
+import { sandboxTest } from '../setup'
+
+// Skip this test if we are running in debug mode — the pwd and user in the testing docker container are not the same as in the actual sandbox.
+sandboxTest('bar', async ({ sandbox }) => {
+ const code = `
+import matplotlib.pyplot as plt
+
+# Prepare data
+authors = ['Author A', 'Author B', 'Author C', 'Author D']
+sales = [100, 200, 300, 400]
+
+# Create and customize the bar chart
+plt.figure(figsize=(10, 6))
+plt.bar(authors, sales, label='Books Sold', color='blue')
+plt.xlabel('Authors')
+plt.ylabel('Number of Books Sold')
+plt.title('Book Sales by Authors')
+
+# Display the chart
+plt.tight_layout()
+plt.show()
+`
+ const result = await sandbox.runCode(code)
+ const chart = result.results[0].chart
+
+ expect(chart).toBeDefined()
+ expect(chart.type).toBe('bar')
+ expect(chart.title).toBe('Book Sales by Authors')
+
+ expect(chart.x_label).toBe('Authors')
+ expect(chart.y_label).toBe('Number of Books Sold')
+
+ expect(chart.x_unit).toBeNull()
+ expect(chart.y_unit).toBeNull()
+
+ const bars = chart.elements
+ expect(bars.length).toBe(4)
+
+ expect(bars.map((bar) => bar.value)).toEqual([100, 200, 300, 400])
+ expect(bars.map((bar) => bar.group)).toEqual([
+ 'Books Sold',
+ 'Books Sold',
+ 'Books Sold',
+ 'Books Sold',
+ ])
+ expect(bars.map((bar) => bar.label)).toEqual([
+ 'Author A',
+ 'Author B',
+ 'Author C',
+ 'Author D',
+ ])
+})
diff --git a/js/tests/charts/boxAndWhisker.test.ts b/js/tests/charts/boxAndWhisker.test.ts
new file mode 100644
index 00000000..47f8985a
--- /dev/null
+++ b/js/tests/charts/boxAndWhisker.test.ts
@@ -0,0 +1,63 @@
+import { expect } from 'vitest'
+
+import { sandboxTest } from '../setup'
+
+sandboxTest('box-and-whisker', async ({ sandbox }) => {
+ const code = `
+import matplotlib.pyplot as plt
+import numpy as np
+
+# Sample data
+data = {
+ 'Class A': [85, 90, 78, 92, 88],
+ 'Class B': [95, 89, 76, 91, 84, 87],
+ 'Class C': [75, 82, 88, 79, 86]
+}
+
+# Create figure and axis
+fig, ax = plt.subplots(figsize=(10, 6))
+
+# Customize plot
+ax.set_title('Exam Scores Distribution')
+ax.set_xlabel('Class')
+ax.set_ylabel('Score')
+
+# Set custom colors
+ax.boxplot(data.values(), labels=data.keys(), patch_artist=True)
+
+# Add legend
+ax.legend()
+
+# Adjust layout and show plot
+plt.tight_layout()
+plt.show()
+`
+ const result = await sandbox.runCode(code)
+ const chart = result.results[0].chart
+
+ expect(chart).toBeDefined()
+
+ expect(chart.type).toBe('box_and_whisker')
+ expect(chart.title).toBe('Exam Scores Distribution')
+
+ expect(chart.x_label).toBe('Class')
+ expect(chart.y_label).toBe('Score')
+
+ expect(chart.x_unit).toBeNull()
+ expect(chart.y_unit).toBeNull()
+
+ const bars = chart.elements
+ expect(bars.length).toBe(3)
+
+ expect(bars.map((bar) => bar.label)).toEqual([
+ 'Class A',
+ 'Class B',
+ 'Class C',
+ ])
+ expect(bars.map((bar) => bar.outliers)).toEqual([[], [76], []])
+ expect(bars.map((bar) => bar.min)).toEqual([78, 84, 75])
+ expect(bars.map((bar) => bar.first_quartile)).toEqual([85, 84.75, 79])
+ expect(bars.map((bar) => bar.median)).toEqual([88, 88, 82])
+ expect(bars.map((bar) => bar.third_quartile)).toEqual([90, 90.5, 86])
+ expect(bars.map((bar) => bar.max)).toEqual([92, 95, 88])
+})
diff --git a/js/tests/charts/line.test.ts b/js/tests/charts/line.test.ts
new file mode 100644
index 00000000..1762bf41
--- /dev/null
+++ b/js/tests/charts/line.test.ts
@@ -0,0 +1,88 @@
+import { expect } from 'vitest'
+
+import { sandboxTest } from '../setup'
+
+sandboxTest('line', async ({ sandbox }) => {
+ const code = `
+import numpy as np
+import matplotlib.pyplot as plt
+import datetime
+
+# Generate x values
+dates = [datetime.date(2023, 9, 1) + datetime.timedelta(seconds=i) for i in range(100)]
+
+x = np.linspace(0, 2*np.pi, 100)
+# Calculate y values
+y_sin = np.sin(x)
+y_cos = np.cos(x)
+
+# Create the plot
+plt.figure(figsize=(10, 6))
+plt.plot(dates, y_sin, label='sin(x)')
+plt.plot(dates, y_cos, label='cos(x)')
+
+# Add labels and title
+plt.xlabel("Time (s)")
+plt.ylabel("Amplitude (Hz)")
+plt.title('Plot of sin(x) and cos(x)')
+
+# Display the plot
+plt.show()
+`
+ const result = await sandbox.runCode(code)
+ const chart = result.results[0].chart
+
+ expect(chart).toBeDefined()
+ expect(chart.type).toBe('line')
+
+ expect(chart.title).toBe('Plot of sin(x) and cos(x)')
+ expect(chart.x_label).toBe('Time (s)')
+ expect(chart.y_label).toBe('Amplitude (Hz)')
+
+ expect(chart.x_scale).toBe('datetime')
+ expect(chart.y_scale).toBe('linear')
+
+ expect(chart.x_unit).toBe('s')
+ expect(chart.y_unit).toBe('Hz')
+
+ expect(chart.x_ticks.every((tick: number) => typeof tick === 'string')).toBe(
+ true
+ )
+ expect(new Date(chart.x_ticks[0])).toBeInstanceOf(Date)
+ expect(chart.y_ticks.every((tick: number) => typeof tick === 'number')).toBe(
+ true
+ )
+
+ expect(
+ chart.y_tick_labels.every((label: string) => typeof label === 'string')
+ ).toBe(true)
+ expect(
+ chart.x_tick_labels.every((label: string) => typeof label === 'string')
+ ).toBe(true)
+
+ const lines = chart.elements
+ expect(lines.length).toBe(2)
+
+ const [firstLine, secondLine] = lines
+
+ expect(firstLine.label).toBe('sin(x)')
+ expect(firstLine.points.length).toBe(100)
+ expect(
+ firstLine.points.every(
+ (point: [number, number]) =>
+ typeof point[0] === 'string' && typeof point[1] === 'number'
+ )
+ ).toBe(true)
+ expect(new Date(firstLine.points[0][0])).toEqual(
+ new Date('2023-09-01T00:00:00.000Z')
+ )
+
+ expect(secondLine.label).toBe('cos(x)')
+ expect(secondLine.points.length).toBe(100)
+ expect(
+ secondLine.points.every(
+ (point: [number, number]) =>
+ typeof point[0] === 'string' && typeof point[1] === 'number'
+ )
+ ).toBe(true)
+})
diff --git a/js/tests/charts/log.test.ts b/js/tests/charts/log.test.ts
new file mode 100644
index 00000000..1569b9a4
--- /dev/null
+++ b/js/tests/charts/log.test.ts
@@ -0,0 +1,66 @@
+import { expect } from 'vitest'
+
+import { sandboxTest } from '../setup'
+
+sandboxTest('log', async ({ sandbox }) => {
+ const code = `
+import numpy as np
+import matplotlib.pyplot as plt
+
+# Generate x values
+x = np.linspace(0, 100, 100)
+# Calculate y values
+y = np.exp(x)
+
+# Create the plot
+plt.figure(figsize=(10, 6))
+plt.plot(x, y, label='y = e^x')
+
+# Set log scale for the y-axis
+plt.yscale('log')
+
+# Add labels and title
+plt.xlabel('X-axis')
+plt.ylabel('Y-axis (log scale)')
+plt.title('Chart with Log Scale on Y-axis')
+
+plt.legend()
+plt.grid(True)
+plt.show()
+`
+
+ const result = await sandbox.runCode(code)
+ const chart = result.results[0].chart
+ expect(chart).toBeDefined()
+ expect(chart.type).toBe('line')
+
+ expect(chart.title).toBe('Chart with Log Scale on Y-axis')
+
+ expect(chart.x_label).toBe('X-axis')
+ expect(chart.y_label).toBe('Y-axis (log scale)')
+
+ expect(chart.x_unit).toBeNull()
+ expect(chart.y_unit).toBe('log scale')
+
+ expect(chart.x_scale).toBe('linear')
+ expect(chart.y_scale).toBe('log')
+
+ expect(chart.x_ticks.every((x) => typeof x === 'number')).toBe(true)
+ expect(chart.y_ticks.every((y) => typeof y === 'number')).toBe(true)
+
+ expect(chart.x_tick_labels.every((x) => typeof x === 'string')).toBe(true)
+ expect(chart.y_tick_labels.every((y) => typeof y === 'string')).toBe(true)
+
+ const lines = chart.elements
+ expect(lines.length).toBe(1)
+
+ const line = lines[0]
+ expect(line.label).toBe('y = e^x')
+ expect(line.points.length).toBe(100)
+
+ expect(
+ line.points.every(
+ ([x, y]) => typeof x === 'number' && typeof y === 'number'
+ )
+ ).toBe(true)
+})
diff --git a/js/tests/charts/pie.test.ts b/js/tests/charts/pie.test.ts
new file mode 100644
index 00000000..1ee5ade8
--- /dev/null
+++ b/js/tests/charts/pie.test.ts
@@ -0,0 +1,49 @@
+import { expect } from 'vitest'
+
+import { sandboxTest } from '../setup'
+
+sandboxTest('pie', async ({ sandbox }) => {
+ const code = `
+import matplotlib.pyplot as plt
+import numpy as np
+
+# Step 1: Define the data for the pie chart
+categories = ["No", "No, in blue"]
+sizes = [90, 10]
+
+# Step 2: Create the figure and axis objects
+fig, ax = plt.subplots(figsize=(8, 8))
+
+plt.xlabel("x")
+plt.ylabel("y")
+
+# Step 3: Create the pie chart
+ax.pie(sizes, labels=categories, autopct='%1.1f%%', startangle=90, colors=plt.cm.Pastel1.colors[:len(categories)])
+
+# Step 4: Add title and legend
+ax.axis('equal') # Equal aspect ratio ensures that pie is drawn as a circle
+plt.title('Will I wake up early tomorrow?')
+
+# Step 5: Show the plot
+plt.show()
+`
+ const result = await sandbox.runCode(code)
+ const chart = result.results[0].chart
+
+ expect(chart).toBeDefined()
+ expect(chart.type).toBe('pie')
+
+ expect(chart.title).toBe('Will I wake up early tomorrow?')
+
+ expect(chart.elements.length).toBe(2)
+
+ const [firstData, secondData] = chart.elements
+
+ expect(firstData.label).toBe('No')
+ expect(firstData.angle).toBe(324) // 90% of 360 degrees
+ expect(firstData.radius).toBe(1)
+
+ expect(secondData.label).toBe('No, in blue')
+ expect(secondData.angle).toBe(36) // 10% of 360 degrees
+ expect(secondData.radius).toBe(1)
+})
diff --git a/js/tests/charts/scales.test.ts b/js/tests/charts/scales.test.ts
new file mode 100644
index 00000000..32a3ecb4
--- /dev/null
+++ b/js/tests/charts/scales.test.ts
@@ -0,0 +1,52 @@
+import { expect } from 'vitest'
+
+import { sandboxTest } from '../setup'
+sandboxTest('datetime scale', async ({ sandbox }) => {
+ const code = `
+ import numpy as np
+ import matplotlib.pyplot as plt
+ import datetime
+
+ # Generate x values
+ dates = [datetime.date(2023, 9, 1) + datetime.timedelta(seconds=i) for i in range(100)]
+ y_sin = np.sin(np.linspace(0, 2*np.pi, 100))
+
+ # Create the plot
+ plt.figure(figsize=(10, 6))
+ plt.plot(dates, y_sin, label='sin(x)')
+ plt.show()
+ `
+
+ const result = await sandbox.runCode(code)
+
+ const chart = result.results[0].chart
+ expect(chart).toBeDefined()
+ expect(chart.type).toBe('line')
+
+ expect(chart.x_scale).toBe('datetime')
+ expect(chart.y_scale).toBe('linear')
+})
+
+sandboxTest('categorical scale', async ({ sandbox }) => {
+ const code = `
+ import numpy as np
+ import matplotlib.pyplot as plt
+
+ x = [1, 2, 3, 4, 5]
+ y = ['A', 'B', 'C', 'D', 'E']
+
+ # Create the plot
+ plt.figure(figsize=(10, 6))
+ plt.plot(x, y)
+ plt.show()
+ `
+
+ const result = await sandbox.runCode(code)
+
+ const chart = result.results[0].chart
+ expect(chart).toBeTruthy()
+
+ expect(chart.type).toBe('line')
+ expect(chart.x_scale).toBe('linear')
+ expect(chart.y_scale).toBe('categorical')
+})
diff --git a/js/tests/charts/scatter.test.ts b/js/tests/charts/scatter.test.ts
new file mode 100644
index 00000000..2d514945
--- /dev/null
+++ b/js/tests/charts/scatter.test.ts
@@ -0,0 +1,70 @@
+import { expect } from 'vitest'
+
+import { sandboxTest } from '../setup'
+
+sandboxTest('scatter', async ({ sandbox }) => {
+ const code = `
+import matplotlib.pyplot as plt
+import numpy as np
+
+# Create data
+N = 5
+x1 = np.random.rand(N)
+y1 = np.random.rand(N)
+x2 = np.random.rand(2*N)
+y2 = np.random.rand(2*N)
+
+plt.xlabel("A")
+plt.ylabel("B")
+
+plt.scatter(x1, y1, c='blue', label='Dataset 1')
+plt.scatter(x2, y2, c='red', label='Dataset 2')
+
+plt.show()
+`
+ const result = await sandbox.runCode(code)
+ const chart = result.results[0].chart
+
+ expect(chart).toBeDefined()
+ expect(chart.type).toBe('scatter')
+
+ expect(chart.title).toBeNull()
+ expect(chart.x_label).toBe('A')
+ expect(chart.y_label).toBe('B')
+
+ expect(chart.x_ticks.every((tick: number) => typeof tick === 'number')).toBe(
+ true
+ )
+ expect(chart.y_ticks.every((tick: number) => typeof tick === 'number')).toBe(
+ true
+ )
+
+ expect(
+ chart.x_tick_labels.every((label: string) => typeof label === 'string')
+ ).toBe(true)
+ expect(
+ chart.y_tick_labels.every((label: string) => typeof label === 'string')
+ ).toBe(true)
+
+ expect(chart.elements.length).toBe(2)
+
+ const [firstData, secondData] = chart.elements
+
+ expect(firstData.label).toBe('Dataset 1')
+ expect(firstData.points.length).toBe(5)
+ expect(
+ firstData.points.every(
+ (point: [number, number]) =>
+ typeof point[0] === 'number' && typeof point[1] === 'number'
+ )
+ ).toBe(true)
+
+ expect(secondData.label).toBe('Dataset 2')
+ expect(secondData.points.length).toBe(10)
+ expect(
+ secondData.points.every(
+ (point: [number, number]) =>
+ typeof point[0] === 'number' && typeof point[1] === 'number'
+ )
+ ).toBe(true)
+})
diff --git a/js/tests/charts/superchart.test.ts b/js/tests/charts/superchart.test.ts
new file mode 100644
index 00000000..33f3c2dd
--- /dev/null
+++ b/js/tests/charts/superchart.test.ts
@@ -0,0 +1,64 @@
+import { expect } from 'vitest'
+
+import { sandboxTest } from '../setup'
+
+sandboxTest('superchart', async ({ sandbox }) => {
+ const code = `
+import matplotlib.pyplot as plt
+import numpy as np
+
+# Data for plotting
+x1 = np.linspace(0, 10, 100)
+y1 = np.sin(x1)
+
+# Create a figure with multiple subplots
+fig, axs = plt.subplots(1, 2, figsize=(10, 8))
+fig.suptitle('Multiple Charts Example', fontsize=16)
+
+# Plotting on the different axes
+axs[0].plot(x1, y1, 'r')
+axs[0].set_title('Sine Wave')
+axs[0].grid(True)
+
+N = 5
+x2 = np.random.rand(N)
+y2 = np.random.rand(N)
+
+axs[1].scatter(x2, y2, c='blue', label='Dataset 1')
+axs[1].set_xlabel('X')
+axs[1].set_ylabel('Y')
+axs[1].set_title('Scatter Plot')
+axs[1].grid(True)
+
+plt.show()
+`
+ const result = await sandbox.runCode(code)
+ const chart = result.results[0].chart
+
+ expect(chart).toBeDefined()
+ expect(chart.type).toBe('superchart')
+ expect(chart.title).toBe('Multiple Charts Example')
+
+ const charts = chart.elements
+ expect(charts.length).toBe(2)
+
+ const [firstChart, secondChart] = charts
+
+ // Check the first chart (LineChart)
+ expect(firstChart.title).toBe('Sine Wave')
+ expect(firstChart.type).toBe('line')
+
+ expect(firstChart.x_label).toBeNull()
+ expect(firstChart.y_label).toBeNull()
+ expect(firstChart.elements.length).toBe(1)
+ expect(firstChart.elements[0].points.length).toBe(100)
+
+ // Check the second chart (ScatterChart)
+ expect(secondChart.title).toBe('Scatter Plot')
+ expect(secondChart.type).toBe('scatter')
+
+ expect(secondChart.x_label).toBe('X')
+ expect(secondChart.y_label).toBe('Y')
+ expect(secondChart.elements.length).toBe(1)
+ expect(secondChart.elements[0].points.length).toBe(5)
+})
diff --git a/js/tests/charts/unknown.test.ts b/js/tests/charts/unknown.test.ts
new file mode 100644
index 00000000..8ab40ebf
--- /dev/null
+++ b/js/tests/charts/unknown.test.ts
@@ -0,0 +1,39 @@
+import { expect } from 'vitest'
+
+import { sandboxTest } from '../setup'
+
+// Skip this test if we are running in debug mode — the pwd and user in the testing docker container are not the same as in the actual sandbox.
+sandboxTest('unknown', async ({ sandbox }) => {
+ const code = `
+import matplotlib.pyplot as plt
+import numpy as np
+
+# Create a figure and an axis
+fig, ax = plt.subplots()
+
+# Create data for two concentric circles
+circle1 = plt.Circle((0, 0), 1, color='blue', fill=False, linewidth=2)
+circle2 = plt.Circle((0, 0), 2, color='red', fill=False, linewidth=2)
+
+# Add the circles to the axes
+ax.add_artist(circle1)
+ax.add_artist(circle2)
+
+# Set grid
+ax.grid(True)
+
+# Set title
+plt.title('Two Concentric Circles')
+
+# Show the plot
+plt.show()
+`
+ const result = await sandbox.runCode(code)
+ const chart = result.results[0].chart
+
+ expect(chart).toBeDefined()
+ expect(chart.type).toBe('unknown')
+ expect(chart.title).toBe('Two Concentric Circles')
+
+ expect(chart.elements.length).toBe(0)
+})
diff --git a/js/tests/contexts.test.ts b/js/tests/contexts.test.ts
new file mode 100644
index 00000000..b0cf9567
--- /dev/null
+++ b/js/tests/contexts.test.ts
@@ -0,0 +1,125 @@
+import { expect } from 'vitest'
+
+import { isDebug, sandboxTest, secureSandboxTest } from './setup'
+
+sandboxTest('create context with no options', async ({ sandbox }) => {
+ const context = await sandbox.createCodeContext()
+
+ const contexts = await sandbox.listCodeContexts()
+ const lastContext = contexts[contexts.length - 1]
+
+ expect(lastContext.id).toBe(context.id)
+ expect(lastContext.language).toBe(context.language)
+ expect(lastContext.cwd).toBe(context.cwd)
+})
+
+sandboxTest('create context with options', async ({ sandbox }) => {
+ const context = await sandbox.createCodeContext({
+ language: 'python',
+ cwd: '/root',
+ })
+
+ const contexts = await sandbox.listCodeContexts()
+ const lastContext = contexts[contexts.length - 1]
+
+ expect(lastContext.id).toBe(context.id)
+ expect(lastContext.language).toBe(context.language)
+ expect(lastContext.cwd).toBe(context.cwd)
+})
+
+sandboxTest('remove context', async ({ sandbox }) => {
+ const context = await sandbox.createCodeContext()
+
+ await sandbox.removeCodeContext(context.id)
+ const contexts = await sandbox.listCodeContexts()
+
+ expect(contexts.map((context) => context.id)).not.toContain(context.id)
+})
+
+sandboxTest('list contexts', async ({ sandbox }) => {
+ const contexts = await sandbox.listCodeContexts()
+
+ // default contexts should include python and javascript
+ expect(contexts.map((context) => context.language)).toContain('python')
+ expect(contexts.map((context) => context.language)).toContain('javascript')
+})
+
+sandboxTest('restart context', async ({ sandbox }) => {
+ const context = await sandbox.createCodeContext()
+
+ // set a variable in the context
+ await sandbox.runCode('x = 1', { context: context })
+
+ // restart the context
+ await sandbox.restartCodeContext(context.id)
+
+ // check that the variable no longer exists
+ const execution = await sandbox.runCode('x', { context: context })
+
+ // check for an NameError with message "name 'x' is not defined"
+ expect(execution.error).toBeDefined()
+ expect(execution.error?.name).toBe('NameError')
+ expect(execution.error?.value).toBe("name 'x' is not defined")
+})
+
+secureSandboxTest.skipIf(isDebug)(
+ 'create context (secure traffic)',
+ async ({ sandbox }) => {
+ const context = await sandbox.createCodeContext()
+
+ const contexts = await sandbox.listCodeContexts()
+ const lastContext = contexts[contexts.length - 1]
+
+ expect(lastContext.id).toBe(context.id)
+ expect(lastContext.language).toBe(context.language)
+ expect(lastContext.cwd).toBe(context.cwd)
+ }
+)
+
+secureSandboxTest.skipIf(isDebug)(
+ 'remove context (secure traffic)',
+ async ({ sandbox }) => {
+ const context = await sandbox.createCodeContext()
+
+ await sandbox.removeCodeContext(context.id)
+ const contexts = await sandbox.listCodeContexts()
+
+ expect(contexts.map((context) => context.id)).not.toContain(context.id)
+
+ await sandbox.kill()
+ }
+)
+
+secureSandboxTest.skipIf(isDebug)(
+ 'list contexts (secure traffic)',
+ async ({ sandbox }) => {
+ const contexts = await sandbox.listCodeContexts()
+
+ // default contexts should include python and javascript
+ expect(contexts.map((context) => context.language)).toContain('python')
+ expect(contexts.map((context) => context.language)).toContain('javascript')
+
+ await sandbox.kill()
+ }
+)
+
+secureSandboxTest.skipIf(isDebug)(
+ 'restart context (secure traffic)',
+ async ({ sandbox }) => {
+ const context = await sandbox.createCodeContext()
+
+ // set a variable in the context
+ await sandbox.runCode('x = 1', { context: context })
+
+ // restart the context
+ await sandbox.restartCodeContext(context.id)
+
+ // check that the variable no longer exists
+ const execution = await sandbox.runCode('x', { context: context })
+
+ // check for an NameError with message "name 'x' is not defined"
+ expect(execution.error).toBeDefined()
+ expect(execution.error?.name).toBe('NameError')
+ expect(execution.error?.value).toBe("name 'x' is not defined")
+ }
+)
diff --git a/js/tests/cwd.test.ts b/js/tests/cwd.test.ts
new file mode 100644
index 00000000..14b671d4
--- /dev/null
+++ b/js/tests/cwd.test.ts
@@ -0,0 +1,49 @@
+import { expect } from 'vitest'
+
+import { isDebug, sandboxTest } from './setup'
+
+// Skip these tests in debug mode — the pwd and user in the testing docker container
+// are not the same as in the actual sandbox.
+
+sandboxTest.skipIf(isDebug)('cwd python', async ({ sandbox }) => {
+ const result = await sandbox.runCode(
+ 'from pathlib import Path; print(Path.cwd())',
+ { language: 'python' }
+ )
+ expect(result.logs.stdout.join().trim()).toEqual('/home/user')
+})
+
+sandboxTest.skipIf(isDebug)('cwd javascript', async ({ sandbox }) => {
+ const result = await sandbox.runCode('process.cwd()', {
+ language: 'js',
+ })
+ expect(result.text).toEqual('/home/user')
+})
+
+sandboxTest.skipIf(isDebug)('cwd typescript', async ({ sandbox }) => {
+ const result = await sandbox.runCode('process.cwd()', {
+ language: 'ts',
+ })
+ expect(result.text).toEqual('/home/user')
+})
+
+sandboxTest.skipIf(isDebug)('cwd r', async ({ sandbox }) => {
+ const result = await sandbox.runCode('getwd()', {
+ language: 'r',
+ })
+ expect(result.results[0]?.text.trim()).toEqual('[1] "/home/user"')
+})
+
+sandboxTest.skipIf(isDebug)('cwd java', async ({ sandbox }) => {
+ const result = await sandbox.runCode('System.getProperty("user.dir")', {
+ language: 'java',
+ })
+ expect(result.results[0]?.text.trim()).toEqual('/home/user')
+})
+
+sandboxTest.skipIf(isDebug)('cwd bash', async ({ sandbox }) => {
+ const result = await sandbox.runCode('pwd', {
+ language: 'bash',
+ })
+ expect(result.logs.stdout.join().trim()).toEqual('/home/user')
+})
diff --git a/js/tests/data.test.ts b/js/tests/data.test.ts
new file mode 100644
index 00000000..b18eeedc
--- /dev/null
+++ b/js/tests/data.test.ts
@@ -0,0 +1,13 @@
+import { expect } from 'vitest'
+
+import { sandboxTest } from './setup'
+
+sandboxTest('get data', async ({ sandbox }) => {
+ const execution = await sandbox.runCode(`
+import pandas as pd
+pd.DataFrame({"a": [1, 2, 3]})
+`)
+
+ const result = execution.results[0]
+ expect(result.data).toBeDefined()
+})
diff --git a/js/tests/defaultKernels.test.ts b/js/tests/defaultKernels.test.ts
new file mode 100644
index 00000000..f5fce337
--- /dev/null
+++ b/js/tests/defaultKernels.test.ts
@@ -0,0 +1,46 @@
+import { expect } from 'vitest'
+
+import { sandboxTest } from './setup'
+
+sandboxTest('test js kernel', async ({ sandbox }) => {
+ const output = await sandbox.runCode('console.log("Hello World!")', {
+ language: 'js',
+ })
+ expect(output.logs.stdout).toEqual(['Hello World!\n'])
+})
+
+sandboxTest('test esm imports', async ({ sandbox }) => {
+ const output = await sandbox.runCode(
+ `
+ import { readFileSync } from 'fs'
+ console.log(typeof readFileSync)
+ `,
+ {
+ language: 'js',
+ }
+ )
+ expect(output.logs.stdout).toEqual(['function\n'])
+})
+
+sandboxTest(
+ 'test top-level await and promise resolution',
+ async ({ sandbox }) => {
+ const output = await sandbox.runCode(
+ `
+ await Promise.resolve('Hello World!')
+ `,
+ {
+ language: 'js',
+ }
+ )
+ expect(output.text).toEqual('Hello World!')
+ }
+)
+
+sandboxTest('test ts kernel', async ({ sandbox }) => {
+ const output = await sandbox.runCode(
+ 'const message: string = "Hello World!"; console.log(message)',
+ { language: 'ts' }
+ )
+ expect(output.logs.stdout).toEqual(['Hello World!\n'])
+})
diff --git a/js/tests/displayData.test.ts b/js/tests/displayData.test.ts
index 6a071a97..ee320c4b 100644
--- a/js/tests/displayData.test.ts
+++ b/js/tests/displayData.test.ts
@@ -1,12 +1,10 @@
-import { CodeInterpreter } from '../src'
+import { expect } from 'vitest'
-import { expect, test } from 'vitest'
+import { sandboxTest } from './setup'
-test('display data', async () => {
- const sandbox = await CodeInterpreter.create()
-
- // plot random graph
- const result = await sandbox.notebook.execCell(`
+sandboxTest('display data', async ({ sandbox }) => {
+ // plot random chart
+ const result = await sandbox.runCode(`
import matplotlib.pyplot as plt
import numpy as np
@@ -20,6 +18,5 @@ test('display data', async () => {
const image = result.results[0]
expect(image.png).toBeDefined()
expect(image.text).toBeDefined()
-
- await sandbox.close()
+ expect(image.extra).toEqual({})
})
diff --git a/js/tests/env_vars/bash.test.ts b/js/tests/env_vars/bash.test.ts
new file mode 100644
index 00000000..49624856
--- /dev/null
+++ b/js/tests/env_vars/bash.test.ts
@@ -0,0 +1,60 @@
+import { expect } from 'vitest'
+
+import { isDebug, sandboxTest } from '../setup'
+import { Sandbox } from '../../src'
+
+// Bash Env Vars
+sandboxTest.skipIf(isDebug)(
+ 'env vars on sandbox (bash)',
+ async ({ template }) => {
+ const sandbox = await Sandbox.create(template, {
+ envs: { TEST_ENV_VAR: 'supertest' },
+ })
+
+ try {
+ const result = await sandbox.runCode('echo $TEST_ENV_VAR', {
+ language: 'bash',
+ })
+
+ expect(result.logs.stdout[0]).toEqual('supertest\n')
+ } finally {
+ await sandbox.kill()
+ }
+ }
+)
+
+sandboxTest('env vars per execution (bash)', async ({ sandbox }) => {
+ const result = await sandbox.runCode('echo $FOO', {
+ envs: { FOO: 'bar' },
+ language: 'bash',
+ })
+
+ const result_empty = await sandbox.runCode('echo ${FOO:-default}', {
+ language: 'bash',
+ })
+
+ expect(result.logs.stdout[0]).toEqual('bar\n')
+ expect(result_empty.logs.stdout[0]).toEqual('default\n')
+})
+
+sandboxTest.skipIf(isDebug)('env vars overwrite', async ({ template }) => {
+ const sandbox = await Sandbox.create(template, {
+ envs: { TEST_ENV_VAR: 'supertest' },
+ })
+
+ try {
+ const result = await sandbox.runCode('echo $TEST_ENV_VAR', {
+ language: 'bash',
+ envs: { TEST_ENV_VAR: 'overwrite' },
+ })
+
+ const result_global_default = await sandbox.runCode('echo $TEST_ENV_VAR', {
+ language: 'bash',
+ })
+
+ expect(result.logs.stdout[0]).toEqual('overwrite\n')
+ expect(result_global_default.logs.stdout[0]).toEqual('supertest\n')
+ } finally {
+ await sandbox.kill()
+ }
+})
diff --git a/js/tests/env_vars/java.test.ts b/js/tests/env_vars/java.test.ts
new file mode 100644
index 00000000..9e7f4d8e
--- /dev/null
+++ b/js/tests/env_vars/java.test.ts
@@ -0,0 +1,69 @@
+import { expect } from 'vitest'
+
+import { isDebug, sandboxTest } from '../setup'
+import { Sandbox } from '../../src'
+
+// Java Env Vars
+sandboxTest.skipIf(isDebug)(
+ 'env vars on sandbox (java)',
+ async ({ template }) => {
+ const sandbox = await Sandbox.create(template, {
+ envs: { TEST_ENV_VAR: 'supertest' },
+ })
+
+ try {
+ const result = await sandbox.runCode(
+ 'System.getProperty("TEST_ENV_VAR")',
+ {
+ language: 'java',
+ }
+ )
+
+ expect(result.results[0]?.text.trim()).toEqual('supertest')
+ } finally {
+ await sandbox.kill()
+ }
+ }
+)
+
+sandboxTest('env vars per execution (java)', async ({ sandbox }) => {
+ const result = await sandbox.runCode('System.getProperty("FOO")', {
+ envs: { FOO: 'bar' },
+ language: 'java',
+ })
+
+ const result_empty = await sandbox.runCode(
+ 'System.getProperty("FOO", "default")',
+ {
+ language: 'java',
+ }
+ )
+
+ expect(result.results[0]?.text.trim()).toEqual('bar')
+ expect(result_empty.results[0]?.text.trim()).toEqual('default')
+})
+
+sandboxTest.skipIf(isDebug)('env vars overwrite', async ({ template }) => {
+ const sandbox = await Sandbox.create(template, {
+ envs: { TEST_ENV_VAR: 'supertest' },
+ })
+
+ try {
+ const result = await sandbox.runCode('System.getProperty("TEST_ENV_VAR")', {
+ language: 'java',
+ envs: { TEST_ENV_VAR: 'overwrite' },
+ })
+
+ const result_global_default = await sandbox.runCode(
+ 'System.getProperty("TEST_ENV_VAR")',
+ {
+ language: 'java',
+ }
+ )
+
+ expect(result.results[0]?.text.trim()).toEqual('overwrite')
+ expect(result_global_default.results[0]?.text.trim()).toEqual('supertest')
+ } finally {
+ await sandbox.kill()
+ }
+})
diff --git a/js/tests/env_vars/js.test.ts b/js/tests/env_vars/js.test.ts
new file mode 100644
index 00000000..7e87f7bb
--- /dev/null
+++ b/js/tests/env_vars/js.test.ts
@@ -0,0 +1,63 @@
+import { expect } from 'vitest'
+
+import { isDebug, sandboxTest } from '../setup'
+import { Sandbox } from '../../src'
+
+// JavaScript Env Vars
+sandboxTest.skipIf(isDebug)(
+ 'env vars on sandbox (javascript)',
+ async ({ template }) => {
+ const sandbox = await Sandbox.create(template, {
+ envs: { TEST_ENV_VAR: 'supertest' },
+ })
+
+ try {
+ const result = await sandbox.runCode('process.env.TEST_ENV_VAR', {
+ language: 'javascript',
+ })
+
+ expect(result.results[0]?.text.trim()).toEqual('supertest')
+ } finally {
+ await sandbox.kill()
+ }
+ }
+)
+
+sandboxTest('env vars per execution (javascript)', async ({ sandbox }) => {
+ const result = await sandbox.runCode('process.env.FOO', {
+ envs: { FOO: 'bar' },
+ language: 'javascript',
+ })
+
+ const result_empty = await sandbox.runCode("process.env.FOO || 'default'", {
+ language: 'javascript',
+ })
+
+ expect(result.results[0]?.text.trim()).toEqual('bar')
+ expect(result_empty.results[0]?.text.trim()).toEqual('default')
+})
+
+sandboxTest.skipIf(isDebug)('env vars overwrite', async ({ template }) => {
+ const sandbox = await Sandbox.create(template, {
+ envs: { TEST_ENV_VAR: 'supertest' },
+ })
+
+ try {
+ const result = await sandbox.runCode('process.env.TEST_ENV_VAR', {
+ language: 'javascript',
+ envs: { TEST_ENV_VAR: 'overwrite' },
+ })
+
+ const result_global_default = await sandbox.runCode(
+ 'process.env.TEST_ENV_VAR',
+ {
+ language: 'javascript',
+ }
+ )
+
+ expect(result.results[0]?.text.trim()).toEqual('overwrite')
+ expect(result_global_default.results[0]?.text.trim()).toEqual('supertest')
+ } finally {
+ await sandbox.kill()
+ }
+})
diff --git a/js/tests/env_vars/python.test.ts b/js/tests/env_vars/python.test.ts
new file mode 100644
index 00000000..af1b7150
--- /dev/null
+++ b/js/tests/env_vars/python.test.ts
@@ -0,0 +1,72 @@
+import { expect } from 'vitest'
+
+import { isDebug, sandboxTest } from '../setup'
+import { Sandbox } from '../../src'
+
+// Python Env Vars
+sandboxTest.skipIf(isDebug)(
+ 'env vars on sandbox (python)',
+ async ({ template }) => {
+ const sandbox = await Sandbox.create(template, {
+ envs: { TEST_ENV_VAR: 'supertest' },
+ })
+
+ try {
+ const result = await sandbox.runCode(
+ 'import os; os.getenv("TEST_ENV_VAR")',
+ {
+ language: 'python',
+ }
+ )
+
+ expect(result.results[0]?.text.trim()).toEqual('supertest')
+ } finally {
+ await sandbox.kill()
+ }
+ }
+)
+
+sandboxTest('env vars per execution (python)', async ({ sandbox }) => {
+ const result = await sandbox.runCode('import os; os.getenv("FOO")', {
+ envs: { FOO: 'bar' },
+ language: 'python',
+ })
+
+ const result_empty = await sandbox.runCode(
+ "import os; os.getenv('FOO', 'default')",
+ {
+ language: 'python',
+ }
+ )
+
+ expect(result.results[0]?.text.trim()).toEqual('bar')
+ expect(result_empty.results[0]?.text.trim()).toEqual('default')
+})
+
+sandboxTest.skipIf(isDebug)('env vars overwrite', async ({ template }) => {
+ const sandbox = await Sandbox.create(template, {
+ envs: { TEST_ENV_VAR: 'supertest' },
+ })
+
+ try {
+ const result = await sandbox.runCode(
+ 'import os; os.getenv("TEST_ENV_VAR")',
+ {
+ language: 'python',
+ envs: { TEST_ENV_VAR: 'overwrite' },
+ }
+ )
+
+ const result_global_default = await sandbox.runCode(
+ 'import os; os.getenv("TEST_ENV_VAR")',
+ {
+ language: 'python',
+ }
+ )
+
+ expect(result.results[0]?.text.trim()).toEqual('overwrite')
+ expect(result_global_default.results[0]?.text.trim()).toEqual('supertest')
+ } finally {
+ await sandbox.kill()
+ }
+})
diff --git a/js/tests/env_vars/r.test.ts b/js/tests/env_vars/r.test.ts
new file mode 100644
index 00000000..0103fec0
--- /dev/null
+++ b/js/tests/env_vars/r.test.ts
@@ -0,0 +1,65 @@
+import { expect } from 'vitest'
+
+import { isDebug, sandboxTest } from '../setup'
+import { Sandbox } from '../../src'
+
+// R Env Vars
+sandboxTest.skipIf(isDebug)('env vars on sandbox (R)', async ({ template }) => {
+ const sandbox = await Sandbox.create(template, {
+ envs: { TEST_ENV_VAR: 'supertest' },
+ })
+
+ try {
+ const result = await sandbox.runCode('Sys.getenv("TEST_ENV_VAR")', {
+ language: 'r',
+ })
+
+ expect(result.results[0]?.text.trim()).toEqual('[1] "supertest"')
+ } finally {
+ await sandbox.kill()
+ }
+})
+
+sandboxTest('env vars per execution (R)', async ({ sandbox }) => {
+ const result = await sandbox.runCode('Sys.getenv("FOO")', {
+ envs: { FOO: 'bar' },
+ language: 'r',
+ })
+
+ const result_empty = await sandbox.runCode(
+ 'Sys.getenv("FOO", unset = "default")',
+ {
+ language: 'r',
+ }
+ )
+
+ expect(result.results[0]?.text.trim()).toEqual('[1] "bar"')
+ expect(result_empty.results[0]?.text.trim()).toEqual('[1] "default"')
+})
+
+sandboxTest.skipIf(isDebug)('env vars overwrite', async ({ template }) => {
+ const sandbox = await Sandbox.create(template, {
+ envs: { TEST_ENV_VAR: 'supertest' },
+ })
+
+ try {
+ const result = await sandbox.runCode('Sys.getenv("TEST_ENV_VAR")', {
+ language: 'r',
+ envs: { TEST_ENV_VAR: 'overwrite' },
+ })
+
+ const result_global_default = await sandbox.runCode(
+ 'Sys.getenv("TEST_ENV_VAR")',
+ {
+ language: 'r',
+ }
+ )
+
+ expect(result.results[0]?.text.trim()).toEqual('[1] "overwrite"')
+ expect(result_global_default.results[0]?.text.trim()).toEqual(
+ '[1] "supertest"'
+ )
+ } finally {
+ await sandbox.kill()
+ }
+})
diff --git a/js/tests/executionCount.test.ts b/js/tests/executionCount.test.ts
new file mode 100644
index 00000000..750aa915
--- /dev/null
+++ b/js/tests/executionCount.test.ts
@@ -0,0 +1,11 @@
+import { expect } from 'vitest'
+
+import { isDebug, sandboxTest } from './setup'
+
+// Skip this test if we are running in debug mode — we don't create new sandbox for each test so the execution number is not reset.
+sandboxTest.skipIf(isDebug)('execution count', async ({ sandbox }) => {
+ await sandbox.runCode('!pwd')
+ const result = await sandbox.runCode('!pwd')
+
+ expect(result.executionCount).toEqual(2)
+})
diff --git a/js/tests/images/bar.test.ts b/js/tests/images/bar.test.ts
new file mode 100644
index 00000000..698b6655
--- /dev/null
+++ b/js/tests/images/bar.test.ts
@@ -0,0 +1,55 @@
+import { expect } from 'vitest'
+
+import { sandboxTest } from '../setup'
+
+// Skip this test if we are running in debug mode — the pwd and user in the testing docker container are not the same as in the actual sandbox.
+sandboxTest('test show image', async ({ sandbox }) => {
+ const code = `
+ import numpy
+ from PIL import Image
+
+ imarray = numpy.random.rand(16,16,3) * 255
+ image = Image.fromarray(imarray.astype('uint8')).convert('RGBA')
+
+ image.show()
+ print("done")
+ `
+
+ const execution = await sandbox.runCode(code)
+
+ const image = execution.results[0].png
+ expect(image).toBeDefined()
+})
+
+sandboxTest('test image represent', async ({ sandbox }) => {
+ const code = `
+ import numpy
+ from PIL import Image
+
+ imarray = numpy.random.rand(16,16,3) * 255
+ image = Image.fromarray(imarray.astype('uint8')).convert('RGBA')
+
+ image
+ `
+ const execution = await sandbox.runCode(code)
+
+ const image = execution.results[0].png
+ expect(image).toBeDefined()
+})
+
+sandboxTest('get image on save', async ({ sandbox }) => {
+ const code = `
+ import numpy
+ from PIL import Image
+
+ imarray = numpy.random.rand(16,16,3) * 255
+ image = Image.fromarray(imarray.astype('uint8')).convert('RGBA')
+
+ image.save("test.png")
+ `
+
+ const execution = await sandbox.runCode(code)
+
+ const image = execution.results[0].png
+ expect(image).toBeDefined()
+})
diff --git a/js/tests/interrupt.test.ts b/js/tests/interrupt.test.ts
new file mode 100644
index 00000000..be4084b0
--- /dev/null
+++ b/js/tests/interrupt.test.ts
@@ -0,0 +1,25 @@
+import { expect } from 'vitest'
+
+import { sandboxTest, wait } from './setup'
+
+sandboxTest(
+ 'subsequent execution works after client timeout',
+ async ({ sandbox }) => {
+ // Start a long-running execution with a short timeout.
+ // This simulates a client disconnect: the SDK aborts the connection,
+ // which should trigger the server to interrupt the kernel (#213).
+ await expect(
+ sandbox.runCode('import time; time.sleep(300)', { timeoutMs: 3_000 })
+ ).rejects.toThrow()
+
+ // Wait for the server to detect the disconnect (via keepalive write
+ // failure) and interrupt the kernel.
+ await wait(5_000)
+
+ // Run a simple execution. Without the kernel interrupt fix, this would
+ // block behind the still-running sleep(30) and time out.
+ const result = await sandbox.runCode('1 + 1', { timeoutMs: 10_000 })
+ expect(result.text).toEqual('2')
+ },
+ 60_000
+)
diff --git a/js/tests/kernels.test.ts b/js/tests/kernels.test.ts
index 548cede9..b45c59db 100644
--- a/js/tests/kernels.test.ts
+++ b/js/tests/kernels.test.ts
@@ -1,48 +1,22 @@
-import { expect, test } from 'vitest'
-import { CodeInterpreter } from '../src'
+import { expect } from 'vitest'
-test('create new kernel', async () => {
- const sandbox = await CodeInterpreter.create()
+import { sandboxTest } from './setup'
- await sandbox.notebook.createKernel()
-
- await sandbox.close()
-})
-
-test('independence of kernels', async () => {
- const sandbox = await CodeInterpreter.create()
- await sandbox.notebook.execCell('x = 1')
- const kernelID = await sandbox.notebook.createKernel()
- const output = await sandbox.notebook.execCell('x', { kernelID })
-
- expect(output.error!.value).toEqual("name 'x' is not defined")
-
- await sandbox.close()
+sandboxTest('create new kernel', async ({ sandbox }) => {
+ await sandbox.createCodeContext()
})
-test('restart kernel', async () => {
- const sandbox = await CodeInterpreter.create()
-
- await sandbox.notebook.execCell('x = 1')
- await sandbox.notebook.restartKernel()
-
- const output = await sandbox.notebook.execCell('x')
+sandboxTest('independence of kernels', async ({ sandbox }) => {
+ await sandbox.runCode('x = 1')
+ const context = await sandbox.createCodeContext()
+ const output = await sandbox.runCode('x', { context })
expect(output.error!.value).toEqual("name 'x' is not defined")
-
- await sandbox.close()
})
-test('list kernels', async () => {
- const sandbox = await CodeInterpreter.create()
-
- let kernels = await sandbox.notebook.listKernels()
- expect(kernels.length).toEqual(1)
-
- const kernelID = await sandbox.notebook.createKernel()
- kernels = await sandbox.notebook.listKernels()
- expect(kernels).toContain(kernelID)
- expect(kernels.length).toEqual(2)
-
- await sandbox.close()
+sandboxTest('pass context and language', async ({ sandbox }) => {
+ const context = await sandbox.createCodeContext()
+ await expect(
+ sandbox.runCode({ context, language: 'python' })
+ ).rejects.toThrowError()
})
diff --git a/js/tests/reconnect.test.ts b/js/tests/reconnect.test.ts
index c4140859..4699fcf1 100644
--- a/js/tests/reconnect.test.ts
+++ b/js/tests/reconnect.test.ts
@@ -1,16 +1,12 @@
-import { CodeInterpreter } from '../src'
+import { expect } from 'vitest'
-import { expect, test } from 'vitest'
+import { Sandbox } from '../src'
+import { isDebug, sandboxTest } from './setup'
-test('reconnect', async () => {
- let sandbox = await CodeInterpreter.create()
- await sandbox.close()
+sandboxTest.skipIf(isDebug)('reconnect', async ({ sandbox }) => {
+ sandbox = await Sandbox.connect(sandbox.sandboxId)
- sandbox = await CodeInterpreter.reconnect(sandbox.id)
-
- const result = await sandbox.notebook.execCell('x =1; x')
+ const result = await sandbox.runCode('x =1; x')
expect(result.text).toEqual('1')
-
- await sandbox.close()
})
diff --git a/js/tests/runtimes/bun/run.test.ts b/js/tests/runtimes/bun/run.test.ts
new file mode 100644
index 00000000..71ee3e14
--- /dev/null
+++ b/js/tests/runtimes/bun/run.test.ts
@@ -0,0 +1,18 @@
+import { expect, test } from 'bun:test'
+
+import { Sandbox } from '../../../src'
+
+test(
+ 'Bun test',
+ async () => {
+ const sbx = await Sandbox.create({ timeoutMs: 5_000 })
+
+ try {
+ const result = await sbx.runCode('print("Hello, World!")')
+ expect(result.logs.stdout.join('')).toEqual('Hello, World!\n')
+ } finally {
+ await sbx.kill()
+ }
+ },
+ { timeout: 30_000 }
+)
diff --git a/js/tests/runtimes/deno/run.test.ts b/js/tests/runtimes/deno/run.test.ts
new file mode 100644
index 00000000..c84d0fa8
--- /dev/null
+++ b/js/tests/runtimes/deno/run.test.ts
@@ -0,0 +1,17 @@
+import { assertEquals } from 'https://deno.land/std@0.224.0/assert/mod.ts'
+import { load } from 'https://deno.land/std@0.224.0/dotenv/mod.ts'
+
+await load({ envPath: '.env', export: true })
+
+import { Sandbox } from '../../../dist/index.mjs'
+
+Deno.test('Deno test', async () => {
+ const sbx = await Sandbox.create({ timeoutMs: 5_000 })
+
+ try {
+ const result = await sbx.runCode('print("Hello, World!")')
+ assertEquals(result.logs.stdout.join(''), 'Hello, World!\n')
+ } finally {
+ await sbx.kill()
+ }
+})
diff --git a/js/tests/setup.ts b/js/tests/setup.ts
new file mode 100644
index 00000000..2f4be79c
--- /dev/null
+++ b/js/tests/setup.ts
@@ -0,0 +1,70 @@
+import { test as base } from 'vitest'
+import { Sandbox, SandboxOpts } from '../src'
+
+interface SandboxFixture {
+ sandbox: Sandbox
+ template: string
+ sandboxTestId: string
+ sandboxOpts: Partial
+}
+
+const template = process.env.E2B_TESTS_TEMPLATE || 'code-interpreter-v1'
+
+export const sandboxTest = base.extend({
+ template,
+ sandboxTestId: [
+ // eslint-disable-next-line no-empty-pattern
+ async ({}, use) => {
+ const id = `test-${generateRandomString()}`
+ await use(id)
+ },
+ { auto: true },
+ ],
+ sandboxOpts: {},
+ sandbox: [
+ async ({ sandboxTestId, sandboxOpts }, use) => {
+ const sandbox = await Sandbox.create(template, {
+ metadata: { sandboxTestId },
+ ...sandboxOpts,
+ })
+ try {
+ await use(sandbox)
+ } finally {
+ try {
+ await sandbox.kill()
+ } catch (err) {
+ if (!isDebug) {
+ console.warn(
+ 'Failed to kill sandbox — this is expected if the test runs with local envd.'
+ )
+ }
+ }
+ }
+ },
+ { auto: false },
+ ],
+})
+
+export const isDebug = process.env.E2B_DEBUG !== undefined
+export const isIntegrationTest = process.env.E2B_INTEGRATION_TEST !== undefined
+
+export const secureSandboxTest = sandboxTest.extend({
+ sandboxOpts: {
+ secure: true,
+ network: {
+ allowPublicTraffic: false,
+ },
+ },
+})
+
+function generateRandomString(length: number = 8): string {
+ return Math.random()
+ .toString(36)
+ .substring(2, length + 2)
+}
+
+export async function wait(ms: number) {
+ return new Promise((resolve) => setTimeout(resolve, ms))
+}
+
+export { template }
diff --git a/js/tests/statefulness.test.ts b/js/tests/statefulness.test.ts
index e763529d..fd5a7e4e 100644
--- a/js/tests/statefulness.test.ts
+++ b/js/tests/statefulness.test.ts
@@ -1,15 +1,12 @@
-import { CodeInterpreter } from '../src'
+import { expect } from 'vitest'
-import { expect, test } from 'vitest'
+import { isDebug, sandboxTest } from './setup'
-test('statefulness', async () => {
- const sandbox = await CodeInterpreter.create()
+// Skip this test if we are running in debug mode — the execution is persisted between all tests so the result is not reset.
+sandboxTest.skipIf(isDebug)('statefulness', async ({ sandbox }) => {
+ await sandbox.runCode('x = 1')
- await sandbox.notebook.execCell('x = 1')
-
- const result = await sandbox.notebook.execCell('x += 1; x')
+ const result = await sandbox.runCode('x += 1; x')
expect(result.text).toEqual('2')
-
- await sandbox.close()
})
diff --git a/js/tests/streaming.test.ts b/js/tests/streaming.test.ts
index 9593c65c..bbf76f81 100644
--- a/js/tests/streaming.test.ts
+++ b/js/tests/streaming.test.ts
@@ -1,35 +1,31 @@
-import { ProcessMessage } from 'e2b'
-import { CodeInterpreter, Result } from '../src'
+import { expect } from 'vitest'
-import { expect, test } from 'vitest'
+import { Result, OutputMessage } from '../src'
-test('streaming output', async () => {
- const out: ProcessMessage[] = []
- const sandbox = await CodeInterpreter.create()
- await sandbox.notebook.execCell('print(1)', {
- onStdout: (msg) => out.push(msg)
+import { sandboxTest } from './setup'
+
+sandboxTest('streaming output', async ({ sandbox }) => {
+ const out: OutputMessage[] = []
+ await sandbox.runCode('print(1)', {
+ onStdout: (msg) => out.push(msg),
})
expect(out.length).toEqual(1)
expect(out[0].line).toEqual('1\n')
- await sandbox.close()
})
-test('streaming error', async () => {
- const out: ProcessMessage[] = []
- const sandbox = await CodeInterpreter.create()
- await sandbox.notebook.execCell('import sys;print(1, file=sys.stderr)', {
- onStderr: (msg) => out.push(msg)
+sandboxTest('streaming error', async ({ sandbox }) => {
+ const out: OutputMessage[] = []
+ await sandbox.runCode('import sys;print(1, file=sys.stderr)', {
+ onStderr: (msg) => out.push(msg),
})
expect(out.length).toEqual(1)
expect(out[0].line).toEqual('1\n')
- await sandbox.close()
})
-test('streaming result', async () => {
+sandboxTest('streaming result', async ({ sandbox }) => {
const out: Result[] = []
- const sandbox = await CodeInterpreter.create()
const code = `
import matplotlib.pyplot as plt
import numpy as np
@@ -42,10 +38,9 @@ test('streaming result', async () => {
x
`
- await sandbox.notebook.execCell(code, {
- onResult: (result) => out.push(result)
+ await sandbox.runCode(code, {
+ onResult: (result) => out.push(result),
})
expect(out.length).toEqual(2)
- await sandbox.close()
})
diff --git a/js/tests/systemd.test.ts b/js/tests/systemd.test.ts
new file mode 100644
index 00000000..28f59398
--- /dev/null
+++ b/js/tests/systemd.test.ts
@@ -0,0 +1,73 @@
+import { expect } from 'vitest'
+import { isDebug, sandboxTest, wait } from './setup'
+
+async function waitForHealth(sandbox: any, maxRetries = 10, intervalMs = 100) {
+ for (let i = 0; i < maxRetries; i++) {
+ try {
+ const result = await sandbox.commands.run(
+ 'curl -s -o /dev/null -w "%{http_code}" http://0.0.0.0:49999/health'
+ )
+ if (result.stdout.trim() === '200') {
+ return true
+ }
+ } catch {
+ // Connection refused or other error, retry
+ }
+ await wait(intervalMs)
+ }
+ return false
+}
+
+sandboxTest.skipIf(isDebug)(
+ 'restart after jupyter kill',
+ async ({ sandbox }) => {
+ // Verify health is up initially
+ const initialHealth = await waitForHealth(sandbox)
+ expect(initialHealth).toBe(true)
+
+ // Kill the jupyter process as root
+ // The command handle may get killed too (since killing jupyter cascades to code-interpreter),
+ // so we catch the error.
+ try {
+ await sandbox.commands.run("kill -9 $(pgrep -f 'jupyter server')", {
+ user: 'root',
+ })
+ } catch {
+ // Expected — the kill cascade may terminate the command handle
+ }
+
+ // Wait for systemd to restart both services
+ const recovered = await waitForHealth(sandbox, 60, 500)
+ expect(recovered).toBe(true)
+
+ // Verify code execution works after recovery
+ const result = await sandbox.runCode('x = 1; x')
+ expect(result.text).toEqual('1')
+ }
+)
+
+sandboxTest.skipIf(isDebug)(
+ 'restart after code-interpreter kill',
+ async ({ sandbox }) => {
+ // Verify health is up initially
+ const initialHealth = await waitForHealth(sandbox)
+ expect(initialHealth).toBe(true)
+
+ // Kill the code-interpreter process as root
+ try {
+ await sandbox.commands.run("kill -9 $(pgrep -f 'uvicorn main:app')", {
+ user: 'root',
+ })
+ } catch {
+ // Expected — killing code-interpreter may terminate the command handle
+ }
+
+ // Wait for systemd to restart it and health to come back
+ const recovered = await waitForHealth(sandbox, 60, 500)
+ expect(recovered).toBe(true)
+
+ // Verify code execution works after recovery
+ const result = await sandbox.runCode('x = 1; x')
+ expect(result.text).toEqual('1')
+ }
+)
diff --git a/js/tsconfig.json b/js/tsconfig.json
index 56772c4b..d660eae3 100644
--- a/js/tsconfig.json
+++ b/js/tsconfig.json
@@ -2,10 +2,7 @@
"compilerOptions": {
"outDir": "dist",
"target": "es6",
- "lib": [
- "dom",
- "ESNext"
- ],
+ "lib": ["dom", "ESNext"],
"sourceMap": true,
"allowJs": true,
"skipLibCheck": true,
@@ -17,14 +14,8 @@
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
- "declaration": true,
+ "declaration": true
},
- "include": [
- "src"
- ],
- "exclude": [
- "dist",
- "node_modules",
- "tsup.config.js"
- ]
-}
\ No newline at end of file
+ "include": ["src"],
+ "exclude": ["dist", "node_modules", "tsup.config.js"]
+}
diff --git a/js/tsup.config.js b/js/tsup.config.js
index 846c9008..c63b850f 100644
--- a/js/tsup.config.js
+++ b/js/tsup.config.js
@@ -2,16 +2,16 @@ import { defineConfig } from 'tsup'
export default defineConfig({
minify: false,
- target: ['es2015'],
+ target: ['es2017'],
sourcemap: true,
dts: true,
format: ['esm', 'cjs'],
clean: true,
entry: {
- index: './src/index.ts'
+ index: './src/index.ts',
},
esbuildOptions: (options) => {
options.legalComments = 'none'
return options
- }
+ },
})
diff --git a/js/vitest.config.mts b/js/vitest.config.mts
new file mode 100644
index 00000000..0a5def20
--- /dev/null
+++ b/js/vitest.config.mts
@@ -0,0 +1,29 @@
+import { defineConfig } from 'vitest/config'
+import { config } from 'dotenv'
+
+const env = config()
+
+export default defineConfig({
+ test: {
+ poolOptions: {
+ threads: {
+ minThreads: 1,
+ maxThreads: 4,
+ },
+ },
+ include: ['tests/**/*.test.ts'],
+ exclude: ['tests/runtimes/**'],
+ globals: false,
+ testTimeout: 30000,
+ environment: 'node',
+ bail: 0,
+ server: {},
+ deps: {
+ interopDefault: true,
+ },
+ env: {
+ ...(process.env as Record),
+ ...env.parsed,
+ },
+ },
+})
diff --git a/js/vitest.config.ts b/js/vitest.config.ts
deleted file mode 100644
index 8afb2e7f..00000000
--- a/js/vitest.config.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { defineConfig } from 'vitest/config'
-
-export default defineConfig({
- test: {
- threads: false,
- setupFiles: ['dotenv/config'],
- globals: false,
- testTimeout: 20000,
- environment: 'node',
- bail: 1,
- server: {},
- deps: {
- interopDefault: true
- }
- }
-})
diff --git a/package.json b/package.json
index a6ee8a34..f09f906b 100644
--- a/package.json
+++ b/package.json
@@ -2,14 +2,25 @@
"name": "e2b-code-interpreter-root",
"private": true,
"scripts": {
- "version": "changeset version && pnpm run -r postVersion",
- "publish": "changeset publish && pnpm run -r postPublish",
- "rm-node-modules": "find . -name 'node_modules' -type d -prune -exec rm -rf '{}' +"
+ "version": "pnpm changeset version && pnpm run -r postVersion",
+ "publish": "pnpm changeset publish && pnpm run -r postPublish",
+ "rm-node-modules": "find . -name 'node_modules' -type d -prune -exec rm -rf '{}' +",
+ "lint": "pnpm --if-present --recursive run lint",
+ "format": "pnpm --if-present --recursive run format",
+ "changeset": "pnpx @changesets/cli"
},
- "packageManager": "pnpm@8.7.6",
+ "packageManager": "pnpm@9.15.9",
"devDependencies": {
- "@changesets/cli": "^2.26.2",
- "@changesets/read": "^0.5.9",
- "changeset": "^0.2.6"
+ "@changesets/read": "^0.6.2",
+ "changeset": "^0.2.6",
+ "@typescript-eslint/eslint-plugin": "^6.7.2",
+ "@typescript-eslint/parser": "^6.7.2",
+ "eslint": "^8.57.1",
+ "eslint-plugin-unused-imports": "^3.0.0",
+ "@stylistic/eslint-plugin-ts": "^1.6.2",
+ "prettier": "^3.6.2"
+ },
+ "engines": {
+ "pnpm": ">=9.0.0 <10"
}
-}
\ No newline at end of file
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 782823ff..164d0200 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1,4 +1,4 @@
-lockfileVersion: '6.0'
+lockfileVersion: '9.0'
settings:
autoInstallPeers: true
@@ -8,5863 +8,3880 @@ importers:
.:
devDependencies:
- '@changesets/cli':
- specifier: ^2.26.2
- version: 2.27.1
'@changesets/read':
- specifier: ^0.5.9
- version: 0.5.9
+ specifier: ^0.6.2
+ version: 0.6.7
+ '@stylistic/eslint-plugin-ts':
+ specifier: ^1.6.2
+ version: 1.8.1(eslint@8.57.1)(typescript@5.7.3)
+ '@typescript-eslint/eslint-plugin':
+ specifier: ^6.7.2
+ version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3)
+ '@typescript-eslint/parser':
+ specifier: ^6.7.2
+ version: 6.21.0(eslint@8.57.1)(typescript@5.7.3)
changeset:
specifier: ^0.2.6
version: 0.2.6
+ eslint:
+ specifier: ^8.57.1
+ version: 8.57.1
+ eslint-plugin-unused-imports:
+ specifier: ^3.0.0
+ version: 3.2.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)
+ prettier:
+ specifier: ^3.6.2
+ version: 3.6.2
+
+ chart_data_extractor:
+ devDependencies:
+ '@typescript-eslint/eslint-plugin':
+ specifier: ^7.11.0
+ version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3)
+ '@typescript-eslint/parser':
+ specifier: ^7.11.0
+ version: 7.18.0(eslint@8.57.1)(typescript@5.7.3)
+ eslint:
+ specifier: ^8.57.1
+ version: 8.57.1
js:
dependencies:
e2b:
- specifier: ^0.16.0
- version: 0.16.0
- isomorphic-ws:
- specifier: ^5.0.0
- version: 5.0.0(ws@8.16.0)
- ws:
- specifier: ^8.15.1
- version: 8.16.0(bufferutil@4.0.8)(utf-8-validate@6.0.3)
+ specifier: ^2.28.0
+ version: 2.28.0
devDependencies:
'@types/node':
- specifier: ^18.18.6
- version: 18.19.26
- '@types/ws':
- specifier: ^8.5.10
- version: 8.5.10
+ specifier: ^20.19.19
+ version: 20.19.41
dotenv:
specifier: ^16.4.5
- version: 16.4.5
+ version: 16.6.1
knip:
- specifier: ^2.34.0
- version: 2.43.0
+ specifier: ^5.25.1
+ version: 5.88.1(@types/node@20.19.41)(typescript@5.7.3)
npm-check-updates:
- specifier: ^16.14.6
- version: 16.14.18
+ specifier: ^17.1.14
+ version: 17.1.18
tsup:
- specifier: ^6.7.0
- version: 6.7.0(typescript@5.4.3)
+ specifier: ^8.5.1
+ version: 8.5.1(jiti@2.7.0)(postcss@8.5.15)(typescript@5.7.3)(yaml@2.9.0)
typescript:
- specifier: ^5.2.2
- version: 5.4.3
+ specifier: ^5.5.3
+ version: 5.7.3
vitest:
- specifier: ^0.34.6
- version: 0.34.6
+ specifier: ^4.1.0
+ version: 4.1.8(@types/node@20.19.41)(vite@7.3.2(@types/node@20.19.41)(jiti@2.7.0)(yaml@2.9.0))
python: {}
-packages:
-
- /@babel/code-frame@7.24.2:
- resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/highlight': 7.24.2
- picocolors: 1.0.0
- dev: true
-
- /@babel/helper-validator-identifier@7.22.20:
- resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==}
- engines: {node: '>=6.9.0'}
- dev: true
+ template: {}
- /@babel/highlight@7.24.2:
- resolution: {integrity: sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/helper-validator-identifier': 7.22.20
- chalk: 2.4.2
- js-tokens: 4.0.0
- picocolors: 1.0.0
- dev: true
+packages:
- /@babel/runtime@7.24.4:
- resolution: {integrity: sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==}
+ '@babel/runtime@7.28.6':
+ resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==}
engines: {node: '>=6.9.0'}
- dependencies:
- regenerator-runtime: 0.14.1
- dev: true
-
- /@changesets/apply-release-plan@7.0.0:
- resolution: {integrity: sha512-vfi69JR416qC9hWmFGSxj7N6wA5J222XNBmezSVATPWDVPIF7gkd4d8CpbEbXmRWbVrkoli3oerGS6dcL/BGsQ==}
- dependencies:
- '@babel/runtime': 7.24.4
- '@changesets/config': 3.0.0
- '@changesets/get-version-range-type': 0.4.0
- '@changesets/git': 3.0.0
- '@changesets/types': 6.0.0
- '@manypkg/get-packages': 1.1.3
- detect-indent: 6.1.0
- fs-extra: 7.0.1
- lodash.startcase: 4.4.0
- outdent: 0.5.0
- prettier: 2.8.8
- resolve-from: 5.0.0
- semver: 7.6.0
- dev: true
-
- /@changesets/assemble-release-plan@6.0.0:
- resolution: {integrity: sha512-4QG7NuisAjisbW4hkLCmGW2lRYdPrKzro+fCtZaILX+3zdUELSvYjpL4GTv0E4aM9Mef3PuIQp89VmHJ4y2bfw==}
- dependencies:
- '@babel/runtime': 7.24.4
- '@changesets/errors': 0.2.0
- '@changesets/get-dependents-graph': 2.0.0
- '@changesets/types': 6.0.0
- '@manypkg/get-packages': 1.1.3
- semver: 7.6.0
- dev: true
-
- /@changesets/changelog-git@0.2.0:
- resolution: {integrity: sha512-bHOx97iFI4OClIT35Lok3sJAwM31VbUM++gnMBV16fdbtBhgYu4dxsphBF/0AZZsyAHMrnM0yFcj5gZM1py6uQ==}
- dependencies:
- '@changesets/types': 6.0.0
- dev: true
-
- /@changesets/cli@2.27.1:
- resolution: {integrity: sha512-iJ91xlvRnnrJnELTp4eJJEOPjgpF3NOh4qeQehM6Ugiz9gJPRZ2t+TsXun6E3AMN4hScZKjqVXl0TX+C7AB3ZQ==}
- hasBin: true
- dependencies:
- '@babel/runtime': 7.24.4
- '@changesets/apply-release-plan': 7.0.0
- '@changesets/assemble-release-plan': 6.0.0
- '@changesets/changelog-git': 0.2.0
- '@changesets/config': 3.0.0
- '@changesets/errors': 0.2.0
- '@changesets/get-dependents-graph': 2.0.0
- '@changesets/get-release-plan': 4.0.0
- '@changesets/git': 3.0.0
- '@changesets/logger': 0.1.0
- '@changesets/pre': 2.0.0
- '@changesets/read': 0.6.0
- '@changesets/types': 6.0.0
- '@changesets/write': 0.3.0
- '@manypkg/get-packages': 1.1.3
- '@types/semver': 7.5.8
- ansi-colors: 4.1.3
- chalk: 2.4.2
- ci-info: 3.9.0
- enquirer: 2.4.1
- external-editor: 3.1.0
- fs-extra: 7.0.1
- human-id: 1.0.2
- meow: 6.1.1
- outdent: 0.5.0
- p-limit: 2.3.0
- preferred-pm: 3.1.3
- resolve-from: 5.0.0
- semver: 7.6.0
- spawndamnit: 2.0.0
- term-size: 2.2.1
- tty-table: 4.2.3
- dev: true
-
- /@changesets/config@3.0.0:
- resolution: {integrity: sha512-o/rwLNnAo/+j9Yvw9mkBQOZySDYyOr/q+wptRLcAVGlU6djOeP9v1nlalbL9MFsobuBVQbZCTp+dIzdq+CLQUA==}
- dependencies:
- '@changesets/errors': 0.2.0
- '@changesets/get-dependents-graph': 2.0.0
- '@changesets/logger': 0.1.0
- '@changesets/types': 6.0.0
- '@manypkg/get-packages': 1.1.3
- fs-extra: 7.0.1
- micromatch: 4.0.5
- dev: true
- /@changesets/errors@0.1.4:
- resolution: {integrity: sha512-HAcqPF7snsUJ/QzkWoKfRfXushHTu+K5KZLJWPb34s4eCZShIf8BFO3fwq6KU8+G7L5KdtN2BzQAXOSXEyiY9Q==}
- dependencies:
- extendable-error: 0.1.7
- dev: true
+ '@bufbuild/protobuf@2.12.0':
+ resolution: {integrity: sha512-B/XlCaFIP8LOwzo+bz5uFzATYokcwCKQcghqnlfwSmM5eX/qTkvDBnDPs+gXtX/RyjxJ4DRikECcPJbyALA8FA==}
- /@changesets/errors@0.2.0:
+ '@changesets/errors@0.2.0':
resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==}
- dependencies:
- extendable-error: 0.1.7
- dev: true
-
- /@changesets/get-dependents-graph@2.0.0:
- resolution: {integrity: sha512-cafUXponivK4vBgZ3yLu944mTvam06XEn2IZGjjKc0antpenkYANXiiE6GExV/yKdsCnE8dXVZ25yGqLYZmScA==}
- dependencies:
- '@changesets/types': 6.0.0
- '@manypkg/get-packages': 1.1.3
- chalk: 2.4.2
- fs-extra: 7.0.1
- semver: 7.6.0
- dev: true
-
- /@changesets/get-release-plan@4.0.0:
- resolution: {integrity: sha512-9L9xCUeD/Tb6L/oKmpm8nyzsOzhdNBBbt/ZNcjynbHC07WW4E1eX8NMGC5g5SbM5z/V+MOrYsJ4lRW41GCbg3w==}
- dependencies:
- '@babel/runtime': 7.24.4
- '@changesets/assemble-release-plan': 6.0.0
- '@changesets/config': 3.0.0
- '@changesets/pre': 2.0.0
- '@changesets/read': 0.6.0
- '@changesets/types': 6.0.0
- '@manypkg/get-packages': 1.1.3
- dev: true
-
- /@changesets/get-version-range-type@0.4.0:
- resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==}
- dev: true
-
- /@changesets/git@2.0.0:
- resolution: {integrity: sha512-enUVEWbiqUTxqSnmesyJGWfzd51PY4H7mH9yUw0hPVpZBJ6tQZFMU3F3mT/t9OJ/GjyiM4770i+sehAn6ymx6A==}
- dependencies:
- '@babel/runtime': 7.24.4
- '@changesets/errors': 0.1.4
- '@changesets/types': 5.2.1
- '@manypkg/get-packages': 1.1.3
- is-subdir: 1.2.0
- micromatch: 4.0.5
- spawndamnit: 2.0.0
- dev: true
- /@changesets/git@3.0.0:
- resolution: {integrity: sha512-vvhnZDHe2eiBNRFHEgMiGd2CT+164dfYyrJDhwwxTVD/OW0FUD6G7+4DIx1dNwkwjHyzisxGAU96q0sVNBns0w==}
- dependencies:
- '@babel/runtime': 7.24.4
- '@changesets/errors': 0.2.0
- '@changesets/types': 6.0.0
- '@manypkg/get-packages': 1.1.3
- is-subdir: 1.2.0
- micromatch: 4.0.5
- spawndamnit: 2.0.0
- dev: true
+ '@changesets/git@3.0.4':
+ resolution: {integrity: sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==}
- /@changesets/logger@0.0.5:
- resolution: {integrity: sha512-gJyZHomu8nASHpaANzc6bkQMO9gU/ib20lqew1rVx753FOxffnCrJlGIeQVxNWCqM+o6OOleCo/ivL8UAO5iFw==}
- dependencies:
- chalk: 2.4.2
- dev: true
+ '@changesets/logger@0.1.1':
+ resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==}
- /@changesets/logger@0.1.0:
- resolution: {integrity: sha512-pBrJm4CQm9VqFVwWnSqKEfsS2ESnwqwH+xR7jETxIErZcfd1u2zBSqrHbRHR7xjhSgep9x2PSKFKY//FAshA3g==}
- dependencies:
- chalk: 2.4.2
- dev: true
+ '@changesets/parse@0.4.3':
+ resolution: {integrity: sha512-ZDmNc53+dXdWEv7fqIUSgRQOLYoUom5Z40gmLgmATmYR9NbL6FJJHwakcCpzaeCy+1D0m0n7mT4jj2B/MQPl7A==}
- /@changesets/parse@0.3.16:
- resolution: {integrity: sha512-127JKNd167ayAuBjUggZBkmDS5fIKsthnr9jr6bdnuUljroiERW7FBTDNnNVyJ4l69PzR57pk6mXQdtJyBCJKg==}
- dependencies:
- '@changesets/types': 5.2.1
- js-yaml: 3.14.1
- dev: true
+ '@changesets/read@0.6.7':
+ resolution: {integrity: sha512-D1G4AUYGrBEk8vj8MGwf75k9GpN6XL3wg8i42P2jZZwFLXnlr2Pn7r9yuQNbaMCarP7ZQWNJbV6XLeysAIMhTA==}
- /@changesets/parse@0.4.0:
- resolution: {integrity: sha512-TS/9KG2CdGXS27S+QxbZXgr8uPsP4yNJYb4BC2/NeFUj80Rni3TeD2qwWmabymxmrLo7JEsytXH1FbpKTbvivw==}
- dependencies:
- '@changesets/types': 6.0.0
- js-yaml: 3.14.1
- dev: true
+ '@changesets/types@4.1.0':
+ resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==}
- /@changesets/pre@2.0.0:
- resolution: {integrity: sha512-HLTNYX/A4jZxc+Sq8D1AMBsv+1qD6rmmJtjsCJa/9MSRybdxh0mjbTvE6JYZQ/ZiQ0mMlDOlGPXTm9KLTU3jyw==}
- dependencies:
- '@babel/runtime': 7.24.4
- '@changesets/errors': 0.2.0
- '@changesets/types': 6.0.0
- '@manypkg/get-packages': 1.1.3
- fs-extra: 7.0.1
- dev: true
+ '@changesets/types@6.1.0':
+ resolution: {integrity: sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==}
- /@changesets/read@0.5.9:
- resolution: {integrity: sha512-T8BJ6JS6j1gfO1HFq50kU3qawYxa4NTbI/ASNVVCBTsKquy2HYwM9r7ZnzkiMe8IEObAJtUVGSrePCOxAK2haQ==}
- dependencies:
- '@babel/runtime': 7.24.4
- '@changesets/git': 2.0.0
- '@changesets/logger': 0.0.5
- '@changesets/parse': 0.3.16
- '@changesets/types': 5.2.1
- chalk: 2.4.2
- fs-extra: 7.0.1
- p-filter: 2.1.0
- dev: true
+ '@connectrpc/connect-web@2.0.0-rc.3':
+ resolution: {integrity: sha512-w88P8Lsn5CCsA7MFRl2e6oLY4J/5toiNtJns/YJrlyQaWOy3RO8pDgkz+iIkG98RPMhj2thuBvsd3Cn4DKKCkw==}
+ peerDependencies:
+ '@bufbuild/protobuf': ^2.2.0
+ '@connectrpc/connect': 2.0.0-rc.3
- /@changesets/read@0.6.0:
- resolution: {integrity: sha512-ZypqX8+/im1Fm98K4YcZtmLKgjs1kDQ5zHpc2U1qdtNBmZZfo/IBiG162RoP0CUF05tvp2y4IspH11PLnPxuuw==}
- dependencies:
- '@babel/runtime': 7.24.4
- '@changesets/git': 3.0.0
- '@changesets/logger': 0.1.0
- '@changesets/parse': 0.4.0
- '@changesets/types': 6.0.0
- chalk: 2.4.2
- fs-extra: 7.0.1
- p-filter: 2.1.0
- dev: true
+ '@connectrpc/connect@2.0.0-rc.3':
+ resolution: {integrity: sha512-ARBt64yEyKbanyRETTjcjJuHr2YXorzQo0etyS5+P6oSeW8xEuzajA9g+zDnMcj1hlX2dQE93foIWQGfpru7gQ==}
+ peerDependencies:
+ '@bufbuild/protobuf': ^2.2.0
- /@changesets/types@4.1.0:
- resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==}
- dev: true
+ '@emnapi/core@1.10.0':
+ resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==}
- /@changesets/types@5.2.1:
- resolution: {integrity: sha512-myLfHbVOqaq9UtUKqR/nZA/OY7xFjQMdfgfqeZIBK4d0hA6pgxArvdv8M+6NUzzBsjWLOtvApv8YHr4qM+Kpfg==}
- dev: true
+ '@emnapi/runtime@1.10.0':
+ resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==}
- /@changesets/types@6.0.0:
- resolution: {integrity: sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==}
- dev: true
+ '@emnapi/wasi-threads@1.2.1':
+ resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==}
- /@changesets/write@0.3.0:
- resolution: {integrity: sha512-slGLb21fxZVUYbyea+94uFiD6ntQW0M2hIKNznFizDhZPDgn2c/fv1UzzlW43RVzh1BEDuIqW6hzlJ1OflNmcw==}
- dependencies:
- '@babel/runtime': 7.24.4
- '@changesets/types': 6.0.0
- fs-extra: 7.0.1
- human-id: 1.0.2
- prettier: 2.8.8
- dev: true
-
- /@colors/colors@1.5.0:
- resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==}
- engines: {node: '>=0.1.90'}
- requiresBuild: true
- dev: true
- optional: true
+ '@esbuild/aix-ppc64@0.27.2':
+ resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
- /@ericcornelissen/bash-parser@0.5.2:
- resolution: {integrity: sha512-4pIMTa1nEFfMXitv7oaNEWOdM+zpOZavesa5GaiWTgda6Zk32CFGxjUp/iIaN0PwgUW1yTq/fztSjbpE8SLGZQ==}
- engines: {node: '>=4'}
- dependencies:
- array-last: 1.3.0
- babylon: 6.18.0
- compose-function: 3.0.3
- deep-freeze: 0.0.1
- filter-iterator: 0.0.1
- filter-obj: 1.1.0
- has-own-property: 0.1.0
- identity-function: 1.0.0
- is-iterable: 1.1.1
- iterable-lookahead: 1.0.0
- lodash.curry: 4.1.1
- magic-string: 0.16.0
- map-obj: 2.0.0
- object-pairs: 0.1.0
- object-values: 1.0.0
- reverse-arguments: 1.0.0
- shell-quote-word: 1.0.1
- to-pascal-case: 1.0.0
- unescape-js: 1.1.4
- dev: true
-
- /@esbuild/aix-ppc64@0.20.2:
- resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==}
- engines: {node: '>=12'}
+ '@esbuild/aix-ppc64@0.27.7':
+ resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==}
+ engines: {node: '>=18'}
cpu: [ppc64]
os: [aix]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/android-arm64@0.17.19:
- resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==}
- engines: {node: '>=12'}
+ '@esbuild/android-arm64@0.27.2':
+ resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==}
+ engines: {node: '>=18'}
cpu: [arm64]
os: [android]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/android-arm64@0.20.2:
- resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==}
- engines: {node: '>=12'}
+ '@esbuild/android-arm64@0.27.7':
+ resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==}
+ engines: {node: '>=18'}
cpu: [arm64]
os: [android]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/android-arm@0.17.19:
- resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==}
- engines: {node: '>=12'}
+ '@esbuild/android-arm@0.27.2':
+ resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==}
+ engines: {node: '>=18'}
cpu: [arm]
os: [android]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/android-arm@0.20.2:
- resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==}
- engines: {node: '>=12'}
+ '@esbuild/android-arm@0.27.7':
+ resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==}
+ engines: {node: '>=18'}
cpu: [arm]
os: [android]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/android-x64@0.17.19:
- resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==}
- engines: {node: '>=12'}
+ '@esbuild/android-x64@0.27.2':
+ resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==}
+ engines: {node: '>=18'}
cpu: [x64]
os: [android]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/android-x64@0.20.2:
- resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==}
- engines: {node: '>=12'}
+ '@esbuild/android-x64@0.27.7':
+ resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==}
+ engines: {node: '>=18'}
cpu: [x64]
os: [android]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/darwin-arm64@0.17.19:
- resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==}
- engines: {node: '>=12'}
+ '@esbuild/darwin-arm64@0.27.2':
+ resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==}
+ engines: {node: '>=18'}
cpu: [arm64]
os: [darwin]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/darwin-arm64@0.20.2:
- resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==}
- engines: {node: '>=12'}
+ '@esbuild/darwin-arm64@0.27.7':
+ resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==}
+ engines: {node: '>=18'}
cpu: [arm64]
os: [darwin]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/darwin-x64@0.17.19:
- resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==}
- engines: {node: '>=12'}
+ '@esbuild/darwin-x64@0.27.2':
+ resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==}
+ engines: {node: '>=18'}
cpu: [x64]
os: [darwin]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/darwin-x64@0.20.2:
- resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==}
- engines: {node: '>=12'}
+ '@esbuild/darwin-x64@0.27.7':
+ resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==}
+ engines: {node: '>=18'}
cpu: [x64]
os: [darwin]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/freebsd-arm64@0.17.19:
- resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==}
- engines: {node: '>=12'}
+ '@esbuild/freebsd-arm64@0.27.2':
+ resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==}
+ engines: {node: '>=18'}
cpu: [arm64]
os: [freebsd]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/freebsd-arm64@0.20.2:
- resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==}
- engines: {node: '>=12'}
+ '@esbuild/freebsd-arm64@0.27.7':
+ resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==}
+ engines: {node: '>=18'}
cpu: [arm64]
os: [freebsd]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/freebsd-x64@0.17.19:
- resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==}
- engines: {node: '>=12'}
+ '@esbuild/freebsd-x64@0.27.2':
+ resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==}
+ engines: {node: '>=18'}
cpu: [x64]
os: [freebsd]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/freebsd-x64@0.20.2:
- resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==}
- engines: {node: '>=12'}
+ '@esbuild/freebsd-x64@0.27.7':
+ resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==}
+ engines: {node: '>=18'}
cpu: [x64]
os: [freebsd]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/linux-arm64@0.17.19:
- resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==}
- engines: {node: '>=12'}
+ '@esbuild/linux-arm64@0.27.2':
+ resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==}
+ engines: {node: '>=18'}
cpu: [arm64]
os: [linux]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/linux-arm64@0.20.2:
- resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==}
- engines: {node: '>=12'}
+ '@esbuild/linux-arm64@0.27.7':
+ resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==}
+ engines: {node: '>=18'}
cpu: [arm64]
os: [linux]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/linux-arm@0.17.19:
- resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==}
- engines: {node: '>=12'}
+ '@esbuild/linux-arm@0.27.2':
+ resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==}
+ engines: {node: '>=18'}
cpu: [arm]
os: [linux]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/linux-arm@0.20.2:
- resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==}
- engines: {node: '>=12'}
+ '@esbuild/linux-arm@0.27.7':
+ resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==}
+ engines: {node: '>=18'}
cpu: [arm]
os: [linux]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/linux-ia32@0.17.19:
- resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==}
- engines: {node: '>=12'}
+ '@esbuild/linux-ia32@0.27.2':
+ resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==}
+ engines: {node: '>=18'}
cpu: [ia32]
os: [linux]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/linux-ia32@0.20.2:
- resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==}
- engines: {node: '>=12'}
+ '@esbuild/linux-ia32@0.27.7':
+ resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==}
+ engines: {node: '>=18'}
cpu: [ia32]
os: [linux]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/linux-loong64@0.17.19:
- resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==}
- engines: {node: '>=12'}
+ '@esbuild/linux-loong64@0.27.2':
+ resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==}
+ engines: {node: '>=18'}
cpu: [loong64]
os: [linux]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/linux-loong64@0.20.2:
- resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==}
- engines: {node: '>=12'}
+ '@esbuild/linux-loong64@0.27.7':
+ resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==}
+ engines: {node: '>=18'}
cpu: [loong64]
os: [linux]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/linux-mips64el@0.17.19:
- resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==}
- engines: {node: '>=12'}
+ '@esbuild/linux-mips64el@0.27.2':
+ resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==}
+ engines: {node: '>=18'}
cpu: [mips64el]
os: [linux]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/linux-mips64el@0.20.2:
- resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==}
- engines: {node: '>=12'}
+ '@esbuild/linux-mips64el@0.27.7':
+ resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==}
+ engines: {node: '>=18'}
cpu: [mips64el]
os: [linux]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/linux-ppc64@0.17.19:
- resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==}
- engines: {node: '>=12'}
+ '@esbuild/linux-ppc64@0.27.2':
+ resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==}
+ engines: {node: '>=18'}
cpu: [ppc64]
os: [linux]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/linux-ppc64@0.20.2:
- resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==}
- engines: {node: '>=12'}
+ '@esbuild/linux-ppc64@0.27.7':
+ resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==}
+ engines: {node: '>=18'}
cpu: [ppc64]
os: [linux]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/linux-riscv64@0.17.19:
- resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==}
- engines: {node: '>=12'}
+ '@esbuild/linux-riscv64@0.27.2':
+ resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==}
+ engines: {node: '>=18'}
cpu: [riscv64]
os: [linux]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/linux-riscv64@0.20.2:
- resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==}
- engines: {node: '>=12'}
+ '@esbuild/linux-riscv64@0.27.7':
+ resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==}
+ engines: {node: '>=18'}
cpu: [riscv64]
os: [linux]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/linux-s390x@0.17.19:
- resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==}
- engines: {node: '>=12'}
+ '@esbuild/linux-s390x@0.27.2':
+ resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==}
+ engines: {node: '>=18'}
cpu: [s390x]
os: [linux]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/linux-s390x@0.20.2:
- resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==}
- engines: {node: '>=12'}
+ '@esbuild/linux-s390x@0.27.7':
+ resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==}
+ engines: {node: '>=18'}
cpu: [s390x]
os: [linux]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/linux-x64@0.17.19:
- resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==}
- engines: {node: '>=12'}
+ '@esbuild/linux-x64@0.27.2':
+ resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==}
+ engines: {node: '>=18'}
cpu: [x64]
os: [linux]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/linux-x64@0.20.2:
- resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==}
- engines: {node: '>=12'}
+ '@esbuild/linux-x64@0.27.7':
+ resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==}
+ engines: {node: '>=18'}
cpu: [x64]
os: [linux]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/netbsd-x64@0.17.19:
- resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==}
- engines: {node: '>=12'}
+ '@esbuild/netbsd-arm64@0.27.2':
+ resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-arm64@0.27.7':
+ resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-x64@0.27.2':
+ resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==}
+ engines: {node: '>=18'}
cpu: [x64]
os: [netbsd]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/netbsd-x64@0.20.2:
- resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==}
- engines: {node: '>=12'}
+ '@esbuild/netbsd-x64@0.27.7':
+ resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==}
+ engines: {node: '>=18'}
cpu: [x64]
os: [netbsd]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/openbsd-x64@0.17.19:
- resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==}
- engines: {node: '>=12'}
+ '@esbuild/openbsd-arm64@0.27.2':
+ resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-arm64@0.27.7':
+ resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-x64@0.27.2':
+ resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==}
+ engines: {node: '>=18'}
cpu: [x64]
os: [openbsd]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/openbsd-x64@0.20.2:
- resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==}
- engines: {node: '>=12'}
+ '@esbuild/openbsd-x64@0.27.7':
+ resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==}
+ engines: {node: '>=18'}
cpu: [x64]
os: [openbsd]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/sunos-x64@0.17.19:
- resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==}
- engines: {node: '>=12'}
+ '@esbuild/openharmony-arm64@0.27.2':
+ resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@esbuild/openharmony-arm64@0.27.7':
+ resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@esbuild/sunos-x64@0.27.2':
+ resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==}
+ engines: {node: '>=18'}
cpu: [x64]
os: [sunos]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/sunos-x64@0.20.2:
- resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==}
- engines: {node: '>=12'}
+ '@esbuild/sunos-x64@0.27.7':
+ resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==}
+ engines: {node: '>=18'}
cpu: [x64]
os: [sunos]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/win32-arm64@0.17.19:
- resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==}
- engines: {node: '>=12'}
+ '@esbuild/win32-arm64@0.27.2':
+ resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==}
+ engines: {node: '>=18'}
cpu: [arm64]
os: [win32]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/win32-arm64@0.20.2:
- resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==}
- engines: {node: '>=12'}
+ '@esbuild/win32-arm64@0.27.7':
+ resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==}
+ engines: {node: '>=18'}
cpu: [arm64]
os: [win32]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/win32-ia32@0.17.19:
- resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==}
- engines: {node: '>=12'}
+ '@esbuild/win32-ia32@0.27.2':
+ resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==}
+ engines: {node: '>=18'}
cpu: [ia32]
os: [win32]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/win32-ia32@0.20.2:
- resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==}
- engines: {node: '>=12'}
+ '@esbuild/win32-ia32@0.27.7':
+ resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==}
+ engines: {node: '>=18'}
cpu: [ia32]
os: [win32]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/win32-x64@0.17.19:
- resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==}
- engines: {node: '>=12'}
+ '@esbuild/win32-x64@0.27.2':
+ resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==}
+ engines: {node: '>=18'}
cpu: [x64]
os: [win32]
- requiresBuild: true
- dev: true
- optional: true
- /@esbuild/win32-x64@0.20.2:
- resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==}
- engines: {node: '>=12'}
+ '@esbuild/win32-x64@0.27.7':
+ resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==}
+ engines: {node: '>=18'}
cpu: [x64]
os: [win32]
- requiresBuild: true
- dev: true
- optional: true
- /@gar/promisify@1.1.3:
- resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==}
- dev: true
+ '@eslint-community/eslint-utils@4.7.0':
+ resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
- /@isaacs/cliui@8.0.2:
- resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
- engines: {node: '>=12'}
- dependencies:
- string-width: 5.1.2
- string-width-cjs: /string-width@4.2.3
- strip-ansi: 7.1.0
- strip-ansi-cjs: /strip-ansi@6.0.1
- wrap-ansi: 8.1.0
- wrap-ansi-cjs: /wrap-ansi@7.0.0
- dev: true
+ '@eslint-community/regexpp@4.12.1':
+ resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==}
+ engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
- /@jest/schemas@29.6.3:
- resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dependencies:
- '@sinclair/typebox': 0.27.8
- dev: true
+ '@eslint/eslintrc@2.1.4':
+ resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+ '@eslint/js@8.57.1':
+ resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+ '@humanwhocodes/config-array@0.13.0':
+ resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==}
+ engines: {node: '>=10.10.0'}
+ deprecated: Use @eslint/config-array instead
- /@jridgewell/gen-mapping@0.3.5:
+ '@humanwhocodes/module-importer@1.0.1':
+ resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
+ engines: {node: '>=12.22'}
+
+ '@humanwhocodes/object-schema@2.0.3':
+ resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==}
+ deprecated: Use @eslint/object-schema instead
+
+ '@isaacs/cliui@9.0.0':
+ resolution: {integrity: sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==}
+ engines: {node: '>=18'}
+
+ '@isaacs/fs-minipass@4.0.1':
+ resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==}
+ engines: {node: '>=18.0.0'}
+
+ '@jridgewell/gen-mapping@0.3.5':
resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==}
engines: {node: '>=6.0.0'}
- dependencies:
- '@jridgewell/set-array': 1.2.1
- '@jridgewell/sourcemap-codec': 1.4.15
- '@jridgewell/trace-mapping': 0.3.25
- dev: true
- /@jridgewell/resolve-uri@3.1.2:
+ '@jridgewell/resolve-uri@3.1.2':
resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
engines: {node: '>=6.0.0'}
- dev: true
- /@jridgewell/set-array@1.2.1:
+ '@jridgewell/set-array@1.2.1':
resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
engines: {node: '>=6.0.0'}
- dev: true
- /@jridgewell/sourcemap-codec@1.4.15:
- resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
- dev: true
+ '@jridgewell/sourcemap-codec@1.5.5':
+ resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
- /@jridgewell/trace-mapping@0.3.25:
+ '@jridgewell/trace-mapping@0.3.25':
resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
- dependencies:
- '@jridgewell/resolve-uri': 3.1.2
- '@jridgewell/sourcemap-codec': 1.4.15
- dev: true
- /@manypkg/find-root@1.1.0:
+ '@manypkg/find-root@1.1.0':
resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==}
- dependencies:
- '@babel/runtime': 7.24.4
- '@types/node': 12.20.55
- find-up: 4.1.0
- fs-extra: 8.1.0
- dev: true
- /@manypkg/get-packages@1.1.3:
+ '@manypkg/get-packages@1.1.3':
resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==}
- dependencies:
- '@babel/runtime': 7.24.4
- '@changesets/types': 4.1.0
- '@manypkg/find-root': 1.1.0
- fs-extra: 8.1.0
- globby: 11.1.0
- read-yaml-file: 1.1.0
- dev: true
- /@nodelib/fs.scandir@2.1.5:
+ '@napi-rs/wasm-runtime@1.1.4':
+ resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==}
+ peerDependencies:
+ '@emnapi/core': ^1.7.1
+ '@emnapi/runtime': ^1.7.1
+
+ '@nodelib/fs.scandir@2.1.5':
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
engines: {node: '>= 8'}
- dependencies:
- '@nodelib/fs.stat': 2.0.5
- run-parallel: 1.2.0
- dev: true
- /@nodelib/fs.stat@2.0.5:
+ '@nodelib/fs.stat@2.0.5':
resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
engines: {node: '>= 8'}
- dev: true
- /@nodelib/fs.walk@1.2.8:
+ '@nodelib/fs.walk@1.2.8':
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
engines: {node: '>= 8'}
- dependencies:
- '@nodelib/fs.scandir': 2.1.5
- fastq: 1.17.1
- dev: true
-
- /@npmcli/fs@2.1.2:
- resolution: {integrity: sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==}
- engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
- dependencies:
- '@gar/promisify': 1.1.3
- semver: 7.6.0
- dev: true
-
- /@npmcli/fs@3.1.0:
- resolution: {integrity: sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dependencies:
- semver: 7.6.0
- dev: true
-
- /@npmcli/git@4.1.0:
- resolution: {integrity: sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dependencies:
- '@npmcli/promise-spawn': 6.0.2
- lru-cache: 7.18.3
- npm-pick-manifest: 8.0.2
- proc-log: 3.0.0
- promise-inflight: 1.0.1
- promise-retry: 2.0.1
- semver: 7.6.0
- which: 3.0.1
- transitivePeerDependencies:
- - bluebird
- dev: true
- /@npmcli/installed-package-contents@2.0.2:
- resolution: {integrity: sha512-xACzLPhnfD51GKvTOOuNX2/V4G4mz9/1I2MfDoye9kBM3RYe5g2YbscsaGoTlaWqkxeiapBWyseULVKpSVHtKQ==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- hasBin: true
- dependencies:
- npm-bundled: 3.0.0
- npm-normalize-package-bin: 3.0.1
- dev: true
+ '@oxc-resolver/binding-android-arm-eabi@11.20.0':
+ resolution: {integrity: sha512-IjfWOXRgJFNdORDl+Uf1aibNgZY2guOD3zmOhx1BGVb/MIiqlFTdmjpQNplSN58lhWehnX4UNqC3QwpUo8pjJg==}
+ cpu: [arm]
+ os: [android]
- /@npmcli/map-workspaces@3.0.4:
- resolution: {integrity: sha512-Z0TbvXkRbacjFFLpVpV0e2mheCh+WzQpcqL+4xp49uNJOxOnIAPZyXtUxZ5Qn3QBTGKA11Exjd9a5411rBrhDg==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dependencies:
- '@npmcli/name-from-folder': 2.0.0
- glob: 10.3.10
- minimatch: 9.0.3
- read-package-json-fast: 3.0.2
- dev: true
+ '@oxc-resolver/binding-android-arm64@11.20.0':
+ resolution: {integrity: sha512-QqslZAuFQG8Q9xm7JuIn8JUbvywhSBMVhuQHtYW+auirZJloS41oxUUaBXk7uUhZJgp44c5zQLeVvmFaDQB+2Q==}
+ cpu: [arm64]
+ os: [android]
- /@npmcli/move-file@2.0.1:
- resolution: {integrity: sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==}
- engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
- deprecated: This functionality has been moved to @npmcli/fs
- dependencies:
- mkdirp: 1.0.4
- rimraf: 3.0.2
- dev: true
-
- /@npmcli/name-from-folder@2.0.0:
- resolution: {integrity: sha512-pwK+BfEBZJbKdNYpHHRTNBwBoqrN/iIMO0AiGvYsp3Hoaq0WbgGSWQR6SCldZovoDpY3yje5lkFUe6gsDgJ2vg==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dev: true
-
- /@npmcli/node-gyp@3.0.0:
- resolution: {integrity: sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dev: true
-
- /@npmcli/promise-spawn@6.0.2:
- resolution: {integrity: sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dependencies:
- which: 3.0.1
- dev: true
-
- /@npmcli/run-script@6.0.2:
- resolution: {integrity: sha512-NCcr1uQo1k5U+SYlnIrbAh3cxy+OQT1VtqiAbxdymSlptbzBb62AjH2xXgjNCoP073hoa1CfCAcwoZ8k96C4nA==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dependencies:
- '@npmcli/node-gyp': 3.0.0
- '@npmcli/promise-spawn': 6.0.2
- node-gyp: 9.4.1
- read-package-json-fast: 3.0.2
- which: 3.0.1
- transitivePeerDependencies:
- - bluebird
- - supports-color
- dev: true
+ '@oxc-resolver/binding-darwin-arm64@11.20.0':
+ resolution: {integrity: sha512-MUcavykj2ewlR+kc5arpg4tC2RvzJkUxWtNv74pf7lcNk00GpIpN43vXMj+j6r4eMmfZhlb8hueKoIb8e9kAGQ==}
+ cpu: [arm64]
+ os: [darwin]
- /@pkgjs/parseargs@0.11.0:
- resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
- engines: {node: '>=14'}
- dev: true
+ '@oxc-resolver/binding-darwin-x64@11.20.0':
+ resolution: {integrity: sha512-BGB16nRUK5Etiv//ihPyzj8Lj1px0mhh4YIfe0FDf045ywknfSm0GEbiRESpr6Q4K82AvnyaRIhhluHByvS4bg==}
+ cpu: [x64]
+ os: [darwin]
- /@pnpm/config.env-replace@1.1.0:
- resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==}
- engines: {node: '>=12.22.0'}
- dev: true
+ '@oxc-resolver/binding-freebsd-x64@11.20.0':
+ resolution: {integrity: sha512-JZgtePaqj3qmD5XFHJaSLWzHRxQu0LaPkdoM1KJXYADvAaa83ijXHclV3ej3CueeW0wxfIAbGCZVP45J0CA7uQ==}
+ cpu: [x64]
+ os: [freebsd]
- /@pnpm/constants@7.1.1:
- resolution: {integrity: sha512-31pZqMtjwV+Vaq7MaPrT1EoDFSYwye3dp6BiHIGRJmVThCQwySRKM7hCvqqI94epNkqFAAYoWrNynWoRYosGdw==}
- engines: {node: '>=16.14'}
- dev: true
+ '@oxc-resolver/binding-linux-arm-gnueabihf@11.20.0':
+ resolution: {integrity: sha512-hOQ/p3ry3v3SchUBXicrrnszaI/UmYzM4wtS4RGfwgVUX7a+HbyQSzJ5aOzu+o6XZkFkS3ZXN4PZAzhOb77OSg==}
+ cpu: [arm]
+ os: [linux]
- /@pnpm/core-loggers@9.0.4(@pnpm/logger@5.0.0):
- resolution: {integrity: sha512-P5IiCwLbYy/vlCDTxEMReB67NVs1Y4ip6iIEM3Y1fbxm0JbPMWTUMKGf2fy7eqGDF3/Vuxk5H7o/A4II6SWzMA==}
- engines: {node: '>=16.14'}
- peerDependencies:
- '@pnpm/logger': ^5.0.0
- dependencies:
- '@pnpm/logger': 5.0.0
- '@pnpm/types': 9.4.0
- dev: true
+ '@oxc-resolver/binding-linux-arm-musleabihf@11.20.0':
+ resolution: {integrity: sha512-2ArPksaw0AqeuGBfoS715VF+JvJQAhD2niWgjE5hVO+L+nAfikVQopvngCMX9x4BD8itWoQ3dnikrQyl5Ho5Jg==}
+ cpu: [arm]
+ os: [linux]
- /@pnpm/error@5.0.2:
- resolution: {integrity: sha512-0TEm+tWNYm+9uh6DSKyRbv8pv/6b4NL0PastLvMxIoqZbBZ5Zj1cYi332R9xsSUi31ZOsu2wpgn/bC7DA9hrjg==}
- engines: {node: '>=16.14'}
- dependencies:
- '@pnpm/constants': 7.1.1
- dev: true
+ '@oxc-resolver/binding-linux-arm64-gnu@11.20.0':
+ resolution: {integrity: sha512-0bJnmYFp62JdZ4nVMDUZ/C58BCZOCcqgKtnUlp7L9Ojf/czIN+3j72YlLPeWLkzlr6SlYvIQA4SGV/HyO0d+qg==}
+ cpu: [arm64]
+ os: [linux]
- /@pnpm/fetching-types@5.0.0:
- resolution: {integrity: sha512-o9gdO1v8Uc5P2fBBuW6GSpfTqIivQmQlqjQJdFiQX0m+tgxlrMRneIg392jZuc6fk7kFqjLheInlslgJfwY+4Q==}
- engines: {node: '>=16.14'}
- dependencies:
- '@zkochan/retry': 0.2.0
- node-fetch: 3.0.0-beta.9
- transitivePeerDependencies:
- - domexception
- dev: true
+ '@oxc-resolver/binding-linux-arm64-musl@11.20.0':
+ resolution: {integrity: sha512-wKHHzPKZo7Ufhv/Bt6yxT7FOgnIgW4gwXcJUipkShGp68W3wGVqvr1Sr0fY65lN0Oy6y41+g2kIDvkgZaMMUkw==}
+ cpu: [arm64]
+ os: [linux]
- /@pnpm/graceful-fs@3.2.0:
- resolution: {integrity: sha512-vRoXJxscDpHak7YE9SqCkzfrayn+Lw+YueOeHIPEqkgokrHeYgYeONoc2kGh0ObHaRtNSsonozVfJ456kxLNvA==}
- engines: {node: '>=16.14'}
- dependencies:
- graceful-fs: 4.2.11
- dev: true
+ '@oxc-resolver/binding-linux-ppc64-gnu@11.20.0':
+ resolution: {integrity: sha512-RN8goF7Ie0B79L4i4G6OeBocTgSC56vJbQ65VJje+oXnldVpLnOU7j/AQ/dP94TcCS+Yh6WG8u3Qt4ETteXFNQ==}
+ cpu: [ppc64]
+ os: [linux]
- /@pnpm/logger@5.0.0:
- resolution: {integrity: sha512-YfcB2QrX+Wx1o6LD1G2Y2fhDhOix/bAY/oAnMpHoNLsKkWIRbt1oKLkIFvxBMzLwAEPqnYWguJrYC+J6i4ywbw==}
- engines: {node: '>=12.17'}
- dependencies:
- bole: 5.0.11
- ndjson: 2.0.0
- dev: true
+ '@oxc-resolver/binding-linux-riscv64-gnu@11.20.0':
+ resolution: {integrity: sha512-5l1yU6/xQEqLZRzxqmMxJfWPslpwCmBsdDGaBvABPehxquCXDC7dd7oraNdKSJUMDXSM7VvVj8H2D2FTjU7oWw==}
+ cpu: [riscv64]
+ os: [linux]
- /@pnpm/network.ca-file@1.0.2:
- resolution: {integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==}
- engines: {node: '>=12.22.0'}
- dependencies:
- graceful-fs: 4.2.10
- dev: true
+ '@oxc-resolver/binding-linux-riscv64-musl@11.20.0':
+ resolution: {integrity: sha512-xHEvkbgz6UC+A3JOyDQy76LkUaxsNSfIr3/GV8slwZsnuooJiIB34gzJfsyvR4JdCYNUUPsRJc/w/oWkODu+hg==}
+ cpu: [riscv64]
+ os: [linux]
- /@pnpm/npm-conf@2.2.2:
- resolution: {integrity: sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==}
- engines: {node: '>=12'}
- dependencies:
- '@pnpm/config.env-replace': 1.1.0
- '@pnpm/network.ca-file': 1.0.2
- config-chain: 1.1.13
- dev: true
+ '@oxc-resolver/binding-linux-s390x-gnu@11.20.0':
+ resolution: {integrity: sha512-aWPDUUmSeyHvlW+SoEUd+JIJsQhVhu6a5tBpDRMu058naPAchTgAVGCFy35zjbnFlt0i8hLWziff6HX0D3LU4g==}
+ cpu: [s390x]
+ os: [linux]
- /@pnpm/npm-package-arg@1.0.0:
- resolution: {integrity: sha512-oQYP08exi6mOPdAZZWcNIGS+KKPsnNwUBzSuAEGWuCcqwMAt3k/WVCqVIXzBxhO5sP2b43og69VHmPj6IroKqw==}
- engines: {node: '>=14.6'}
- dependencies:
- hosted-git-info: 4.1.0
- semver: 7.6.0
- validate-npm-package-name: 4.0.0
- dev: true
+ '@oxc-resolver/binding-linux-x64-gnu@11.20.0':
+ resolution: {integrity: sha512-x2YeSimvhJjKLVD8KSu8f/rqU1potcdEMkApIPJqjZWN7c2Fpt4g2X32WDg1p+XDAmyT7nuQGe0vnhvXeLbH+g==}
+ cpu: [x64]
+ os: [linux]
- /@pnpm/npm-resolver@18.0.0(@pnpm/logger@5.0.0):
- resolution: {integrity: sha512-FGHmnRjSf7tQHagk6bMrUtHvZbz3ROUoGRDrpMyqJo///+S7SZt/hSDS77PhZ7T6PRXipkFyUtRkqtHmGKFCAg==}
- engines: {node: '>=16.14'}
- peerDependencies:
- '@pnpm/logger': ^5.0.0
- dependencies:
- '@pnpm/core-loggers': 9.0.4(@pnpm/logger@5.0.0)
- '@pnpm/error': 5.0.2
- '@pnpm/fetching-types': 5.0.0
- '@pnpm/graceful-fs': 3.2.0
- '@pnpm/logger': 5.0.0
- '@pnpm/resolve-workspace-range': 5.0.1
- '@pnpm/resolver-base': 11.0.0
- '@pnpm/types': 9.4.0
- '@zkochan/retry': 0.2.0
- encode-registry: 3.0.1
- load-json-file: 6.2.0
- lru-cache: 10.2.0
- normalize-path: 3.0.0
- p-limit: 3.1.0
- p-memoize: 4.0.1
- parse-npm-tarball-url: 3.0.0
- path-temp: 2.1.0
- ramda: /@pnpm/ramda@0.28.1
- rename-overwrite: 4.0.4
- semver: 7.6.0
- ssri: 10.0.5
- version-selector-type: 3.0.0
- transitivePeerDependencies:
- - domexception
- dev: true
+ '@oxc-resolver/binding-linux-x64-musl@11.20.0':
+ resolution: {integrity: sha512-kcRLEIxpZefeYfLChjpgFf3ilBzRDZ+yobMrpRsQlSrxuFGtm3U6PMU7AaEpMqo3NfDGVyJJseAjnRLzMFHjwQ==}
+ cpu: [x64]
+ os: [linux]
- /@pnpm/ramda@0.28.1:
- resolution: {integrity: sha512-zcAG+lvU0fMziNeGXpPyCyCJYp5ZVrPElEE4t14jAmViaihohocZ+dDkcRIyAomox8pQsuZnv1EyHR+pOhmUWw==}
- dev: true
+ '@oxc-resolver/binding-openharmony-arm64@11.20.0':
+ resolution: {integrity: sha512-HHcfnApSZGtKhTiHqe8OZruOZe5XuFQH5/E0Yhj3u8fnFvzkM4/k6WjacUf4SvA0SPEAbfbgYmVPuo0VX/fIBQ==}
+ cpu: [arm64]
+ os: [openharmony]
- /@pnpm/resolve-workspace-range@5.0.1:
- resolution: {integrity: sha512-yQ0pMthlw8rTgS/C9hrjne+NEnnSNevCjtdodd7i15I59jMBYciHifZ/vjg0NY+Jl+USTc3dBE+0h/4tdYjMKg==}
- engines: {node: '>=16.14'}
- dependencies:
- semver: 7.6.0
- dev: true
+ '@oxc-resolver/binding-wasm32-wasi@11.20.0':
+ resolution: {integrity: sha512-Tn0y1XOFYHNfK1wp1Z5QK8Rcld/bsOwRISQXfqAZ5IBpv8Gz1IvV39fUWNprqNdRizgcvFhOzWwFun2zkJsyBg==}
+ engines: {node: '>=14.0.0'}
+ cpu: [wasm32]
- /@pnpm/resolver-base@11.0.0:
- resolution: {integrity: sha512-oxfjO8Ie6aBQPXSqOWGJP9s0xj9Z4cbRI7fK63WKhjwmNH4CTrSfikRL2o4FoXo2APAbJEUp2lCxx+86dq2tUg==}
- engines: {node: '>=16.14'}
- dependencies:
- '@pnpm/types': 9.4.0
- dev: true
+ '@oxc-resolver/binding-win32-arm64-msvc@11.20.0':
+ resolution: {integrity: sha512-qPi25YNPe4YenS8MgsQU2+bIFHxxpLx1LVna2444cEHqNPhNjvWf9zqj4aWE43H9LpAsTmkkAlA3eL5ElBU3mA==}
+ cpu: [arm64]
+ os: [win32]
- /@pnpm/types@9.4.0:
- resolution: {integrity: sha512-IRDuIuNobLRQe0UyY2gbrrTzYS46tTNvOEfL6fOf0Qa8NyxUzeXz946v7fQuQE3LSBf8ENBC5SXhRmDl+mBEqA==}
- engines: {node: '>=16.14'}
- dev: true
+ '@oxc-resolver/binding-win32-x64-msvc@11.20.0':
+ resolution: {integrity: sha512-Wb14jWEW8huH6It9F6sXd9vrYmIS7pMrgkU6sxpLxkP+9z+wRgs71hUEhRpcn8FOXAFa27FVWfY2tRpbfTzfLw==}
+ cpu: [x64]
+ os: [win32]
- /@pnpm/workspace.pkgs-graph@2.0.11(@pnpm/logger@5.0.0):
- resolution: {integrity: sha512-VRX7E7pX92C0akCMYGzsTqJoOwQS7/8R40pAPK7smgaEpKeEgVThqnIXt+wPdseD5CzS7OzMaIWlT3WXr3O5rQ==}
- engines: {node: '>=16.14'}
- dependencies:
- '@pnpm/npm-package-arg': 1.0.0
- '@pnpm/npm-resolver': 18.0.0(@pnpm/logger@5.0.0)
- '@pnpm/resolve-workspace-range': 5.0.1
- ramda: /@pnpm/ramda@0.28.1
- transitivePeerDependencies:
- - '@pnpm/logger'
- - domexception
- dev: true
+ '@rollup/rollup-android-arm-eabi@4.39.0':
+ resolution: {integrity: sha512-lGVys55Qb00Wvh8DMAocp5kIcaNzEFTmGhfFd88LfaogYTRKrdxgtlO5H6S49v2Nd8R2C6wLOal0qv6/kCkOwA==}
+ cpu: [arm]
+ os: [android]
- /@rollup/rollup-android-arm-eabi@4.13.0:
- resolution: {integrity: sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==}
+ '@rollup/rollup-android-arm-eabi@4.61.0':
+ resolution: {integrity: sha512-dnxczajOqt0gesZlN5pGQ1s1imQVrsmCw5G2Ci4oM+0WvNz3pyRnlWrT7McoZIb8VlFwCawdmbWRmxRn7HI+VQ==}
cpu: [arm]
os: [android]
- requiresBuild: true
- dev: true
- optional: true
- /@rollup/rollup-android-arm64@4.13.0:
- resolution: {integrity: sha512-BSbaCmn8ZadK3UAQdlauSvtaJjhlDEjS5hEVVIN3A4bbl3X+otyf/kOJV08bYiRxfejP3DXFzO2jz3G20107+Q==}
+ '@rollup/rollup-android-arm64@4.39.0':
+ resolution: {integrity: sha512-It9+M1zE31KWfqh/0cJLrrsCPiF72PoJjIChLX+rEcujVRCb4NLQ5QzFkzIZW8Kn8FTbvGQBY5TkKBau3S8cCQ==}
+ cpu: [arm64]
+ os: [android]
+
+ '@rollup/rollup-android-arm64@4.61.0':
+ resolution: {integrity: sha512-Bp3JpGP00Vu3f238ivRrjf7z3xSzVPXqCmaJYA9t2c+c8vKYvOzmXF7LkkeUalTEGd6cZcSWe+PFIP3Vy48fRg==}
cpu: [arm64]
os: [android]
- requiresBuild: true
- dev: true
- optional: true
- /@rollup/rollup-darwin-arm64@4.13.0:
- resolution: {integrity: sha512-Ovf2evVaP6sW5Ut0GHyUSOqA6tVKfrTHddtmxGQc1CTQa1Cw3/KMCDEEICZBbyppcwnhMwcDce9ZRxdWRpVd6g==}
+ '@rollup/rollup-darwin-arm64@4.39.0':
+ resolution: {integrity: sha512-lXQnhpFDOKDXiGxsU9/l8UEGGM65comrQuZ+lDcGUx+9YQ9dKpF3rSEGepyeR5AHZ0b5RgiligsBhWZfSSQh8Q==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@rollup/rollup-darwin-arm64@4.61.0':
+ resolution: {integrity: sha512-zaYIpr670mUmmZ1tVzUFplbQbG7h3Gugx3L5FoqhsC2m/YnLlR1a7zVLmXNPy+iY1tFPEbNG+HHBXZGyId0G5w==}
cpu: [arm64]
os: [darwin]
- requiresBuild: true
- dev: true
- optional: true
- /@rollup/rollup-darwin-x64@4.13.0:
- resolution: {integrity: sha512-U+Jcxm89UTK592vZ2J9st9ajRv/hrwHdnvyuJpa5A2ngGSVHypigidkQJP+YiGL6JODiUeMzkqQzbCG3At81Gg==}
+ '@rollup/rollup-darwin-x64@4.39.0':
+ resolution: {integrity: sha512-mKXpNZLvtEbgu6WCkNij7CGycdw9cJi2k9v0noMb++Vab12GZjFgUXD69ilAbBh034Zwn95c2PNSz9xM7KYEAQ==}
cpu: [x64]
os: [darwin]
- requiresBuild: true
- dev: true
- optional: true
- /@rollup/rollup-linux-arm-gnueabihf@4.13.0:
- resolution: {integrity: sha512-8wZidaUJUTIR5T4vRS22VkSMOVooG0F4N+JSwQXWSRiC6yfEsFMLTYRFHvby5mFFuExHa/yAp9juSphQQJAijQ==}
- cpu: [arm]
- os: [linux]
- requiresBuild: true
- dev: true
- optional: true
+ '@rollup/rollup-darwin-x64@4.61.0':
+ resolution: {integrity: sha512-+P49fvkv2dSoeevUW+lgZ/I2JHSsJCK1Lyjj7Cu6E4UHG4tS9XIefzIjo5qhgELjAclnen1rLzK2PMKJdo+Dyg==}
+ cpu: [x64]
+ os: [darwin]
- /@rollup/rollup-linux-arm64-gnu@4.13.0:
- resolution: {integrity: sha512-Iu0Kno1vrD7zHQDxOmvweqLkAzjxEVqNhUIXBsZ8hu8Oak7/5VTPrxOEZXYC1nmrBVJp0ZcL2E7lSuuOVaE3+w==}
+ '@rollup/rollup-freebsd-arm64@4.39.0':
+ resolution: {integrity: sha512-jivRRlh2Lod/KvDZx2zUR+I4iBfHcu2V/BA2vasUtdtTN2Uk3jfcZczLa81ESHZHPHy4ih3T/W5rPFZ/hX7RtQ==}
cpu: [arm64]
- os: [linux]
- requiresBuild: true
- dev: true
- optional: true
+ os: [freebsd]
- /@rollup/rollup-linux-arm64-musl@4.13.0:
- resolution: {integrity: sha512-C31QrW47llgVyrRjIwiOwsHFcaIwmkKi3PCroQY5aVq4H0A5v/vVVAtFsI1nfBngtoRpeREvZOkIhmRwUKkAdw==}
+ '@rollup/rollup-freebsd-arm64@4.61.0':
+ resolution: {integrity: sha512-l3FAAOyKJXH2ea6KNFN+MMgC/rnE94YGLXs2ehYqDcCoHt1DpvgWX75BhUJxN38XojP7Ul+4H8PRn7EdyqSDrw==}
cpu: [arm64]
+ os: [freebsd]
+
+ '@rollup/rollup-freebsd-x64@4.39.0':
+ resolution: {integrity: sha512-8RXIWvYIRK9nO+bhVz8DwLBepcptw633gv/QT4015CpJ0Ht8punmoHU/DuEd3iw9Hr8UwUV+t+VNNuZIWYeY7Q==}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@rollup/rollup-freebsd-x64@4.61.0':
+ resolution: {integrity: sha512-VokPN3TSctKj65cyCNPaUh4vMFA8awxOot/0sp+4J7ZlNRKQEhXhawqPwajoi8H5ZFt61i0ugZJuTKXBjGJ17Q==}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.39.0':
+ resolution: {integrity: sha512-mz5POx5Zu58f2xAG5RaRRhp3IZDK7zXGk5sdEDj4o96HeaXhlUwmLFzNlc4hCQi5sGdR12VDgEUqVSHer0lI9g==}
+ cpu: [arm]
os: [linux]
- requiresBuild: true
- dev: true
- optional: true
- /@rollup/rollup-linux-riscv64-gnu@4.13.0:
- resolution: {integrity: sha512-Oq90dtMHvthFOPMl7pt7KmxzX7E71AfyIhh+cPhLY9oko97Zf2C9tt/XJD4RgxhaGeAraAXDtqxvKE1y/j35lA==}
- cpu: [riscv64]
+ '@rollup/rollup-linux-arm-gnueabihf@4.61.0':
+ resolution: {integrity: sha512-DxH0P3wxm+Yzs/p3zrk9dw1rURu8p0Nv5+MRK/L7OtnLNg5rLZraSBFZ8iUXOd9f2BlhJyEpIZUH/emjq4UJ4g==}
+ cpu: [arm]
os: [linux]
- requiresBuild: true
- dev: true
- optional: true
- /@rollup/rollup-linux-x64-gnu@4.13.0:
- resolution: {integrity: sha512-yUD/8wMffnTKuiIsl6xU+4IA8UNhQ/f1sAnQebmE/lyQ8abjsVyDkyRkWop0kdMhKMprpNIhPmYlCxgHrPoXoA==}
- cpu: [x64]
+ '@rollup/rollup-linux-arm-musleabihf@4.39.0':
+ resolution: {integrity: sha512-+YDwhM6gUAyakl0CD+bMFpdmwIoRDzZYaTWV3SDRBGkMU/VpIBYXXEvkEcTagw/7VVkL2vA29zU4UVy1mP0/Yw==}
+ cpu: [arm]
os: [linux]
- requiresBuild: true
- dev: true
- optional: true
- /@rollup/rollup-linux-x64-musl@4.13.0:
- resolution: {integrity: sha512-9RyNqoFNdF0vu/qqX63fKotBh43fJQeYC98hCaf89DYQpv+xu0D8QFSOS0biA7cGuqJFOc1bJ+m2rhhsKcw1hw==}
- cpu: [x64]
+ '@rollup/rollup-linux-arm-musleabihf@4.61.0':
+ resolution: {integrity: sha512-T6ZvMNe84kAz6TBWHC7hGAoEtzP1LWYw/AqayGWEF6uISt3Abk/st06LqRD9THd7Xz3NxzurUpzAuEAUbZf+nw==}
+ cpu: [arm]
os: [linux]
- requiresBuild: true
- dev: true
- optional: true
- /@rollup/rollup-win32-arm64-msvc@4.13.0:
- resolution: {integrity: sha512-46ue8ymtm/5PUU6pCvjlic0z82qWkxv54GTJZgHrQUuZnVH+tvvSP0LsozIDsCBFO4VjJ13N68wqrKSeScUKdA==}
+ '@rollup/rollup-linux-arm64-gnu@4.39.0':
+ resolution: {integrity: sha512-EKf7iF7aK36eEChvlgxGnk7pdJfzfQbNvGV/+l98iiMwU23MwvmV0Ty3pJ0p5WQfm3JRHOytSIqD9LB7Bq7xdQ==}
cpu: [arm64]
- os: [win32]
- requiresBuild: true
- dev: true
- optional: true
+ os: [linux]
- /@rollup/rollup-win32-ia32-msvc@4.13.0:
- resolution: {integrity: sha512-P5/MqLdLSlqxbeuJ3YDeX37srC8mCflSyTrUsgbU1c/U9j6l2g2GiIdYaGD9QjdMQPMSgYm7hgg0551wHyIluw==}
- cpu: [ia32]
- os: [win32]
- requiresBuild: true
- dev: true
- optional: true
+ '@rollup/rollup-linux-arm64-gnu@4.61.0':
+ resolution: {integrity: sha512-q/4hzvQkDs8b4jIBab1pnLiiM0ayTZsN2amBFPDzuyZxjEd4wDwx0UJFYM3cOZzSf5Kw8fnWSprJzIBMkcR44Q==}
+ cpu: [arm64]
+ os: [linux]
- /@rollup/rollup-win32-x64-msvc@4.13.0:
- resolution: {integrity: sha512-UKXUQNbO3DOhzLRwHSpa0HnhhCgNODvfoPWv2FCXme8N/ANFfhIPMGuOT+QuKd16+B5yxZ0HdpNlqPvTMS1qfw==}
- cpu: [x64]
- os: [win32]
- requiresBuild: true
- dev: true
- optional: true
+ '@rollup/rollup-linux-arm64-musl@4.39.0':
+ resolution: {integrity: sha512-vYanR6MtqC7Z2SNr8gzVnzUul09Wi1kZqJaek3KcIlI/wq5Xtq4ZPIZ0Mr/st/sv/NnaPwy/D4yXg5x0B3aUUA==}
+ cpu: [arm64]
+ os: [linux]
- /@sigstore/bundle@1.1.0:
- resolution: {integrity: sha512-PFutXEy0SmQxYI4texPw3dd2KewuNqv7OuK1ZFtY2fM754yhvG2KdgwIhRnoEE2uHdtdGNQ8s0lb94dW9sELog==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dependencies:
- '@sigstore/protobuf-specs': 0.2.1
- dev: true
+ '@rollup/rollup-linux-arm64-musl@4.61.0':
+ resolution: {integrity: sha512-vvYWX3akdEAY6km+9wAqFDnk6pQsbJKVnj7xawcvs/+fdlYBGp+U+Qq/lLfpIxYIZvZLHMAKD9HLdacSx/r3dw==}
+ cpu: [arm64]
+ os: [linux]
- /@sigstore/protobuf-specs@0.2.1:
- resolution: {integrity: sha512-XTWVxnWJu+c1oCshMLwnKvz8ZQJJDVOlciMfgpJBQbThVjKTCG8dwyhgLngBD2KN0ap9F/gOV8rFDEx8uh7R2A==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dev: true
+ '@rollup/rollup-linux-loong64-gnu@4.61.0':
+ resolution: {integrity: sha512-DePa5cqOxDP/Zp0VOXpeWaGew5iIv5DXp9NYbzkX5PFQyWVX9184WCTh3hvr/7lhXo8ZVlbFLkz8+o/q1dU6gA==}
+ cpu: [loong64]
+ os: [linux]
- /@sigstore/sign@1.0.0:
- resolution: {integrity: sha512-INxFVNQteLtcfGmcoldzV6Je0sbbfh9I16DM4yJPw3j5+TFP8X6uIiA18mvpEa9yyeycAKgPmOA3X9hVdVTPUA==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dependencies:
- '@sigstore/bundle': 1.1.0
- '@sigstore/protobuf-specs': 0.2.1
- make-fetch-happen: 11.1.1
- transitivePeerDependencies:
- - supports-color
- dev: true
+ '@rollup/rollup-linux-loong64-musl@4.61.0':
+ resolution: {integrity: sha512-LV8aWMB8UChglMCEzs7RkN0GsH29RJaLLqwm9fCIjlqwxQTiWAqNcc7wjBkH31hV0PU/yVxGYvrYsgfea2qw6g==}
+ cpu: [loong64]
+ os: [linux]
- /@sigstore/tuf@1.0.3:
- resolution: {integrity: sha512-2bRovzs0nJZFlCN3rXirE4gwxCn97JNjMmwpecqlbgV9WcxX7WRuIrgzx/X7Ib7MYRbyUTpBYE0s2x6AmZXnlg==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dependencies:
- '@sigstore/protobuf-specs': 0.2.1
- tuf-js: 1.1.7
- transitivePeerDependencies:
- - supports-color
- dev: true
+ '@rollup/rollup-linux-loongarch64-gnu@4.39.0':
+ resolution: {integrity: sha512-NMRUT40+h0FBa5fb+cpxtZoGAggRem16ocVKIv5gDB5uLDgBIwrIsXlGqYbLwW8YyO3WVTk1FkFDjMETYlDqiw==}
+ cpu: [loong64]
+ os: [linux]
- /@sinclair/typebox@0.27.8:
- resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
- dev: true
+ '@rollup/rollup-linux-powerpc64le-gnu@4.39.0':
+ resolution: {integrity: sha512-0pCNnmxgduJ3YRt+D+kJ6Ai/r+TaePu9ZLENl+ZDV/CdVczXl95CbIiwwswu4L+K7uOIGf6tMo2vm8uadRaICQ==}
+ cpu: [ppc64]
+ os: [linux]
- /@sindresorhus/is@5.6.0:
- resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==}
- engines: {node: '>=14.16'}
- dev: true
+ '@rollup/rollup-linux-ppc64-gnu@4.61.0':
+ resolution: {integrity: sha512-QoNSnwQtaeNu5grdBbsL0tt1uyl5EnS8DA8Mr3nluMXbhdQNyhN+G4tBax7VCdxLKj8YJ0/4OO9Ho84jMnJtKA==}
+ cpu: [ppc64]
+ os: [linux]
- /@snyk/github-codeowners@1.1.0:
- resolution: {integrity: sha512-lGFf08pbkEac0NYgVf4hdANpAgApRjNByLXB+WBip3qj1iendOIyAwP2GKkKbQMNVy2r1xxDf0ssfWscoiC+Vw==}
- engines: {node: '>=8.10'}
- hasBin: true
- dependencies:
- commander: 4.1.1
- ignore: 5.3.1
- p-map: 4.0.0
- dev: true
+ '@rollup/rollup-linux-ppc64-musl@4.61.0':
+ resolution: {integrity: sha512-/zZp5MKapIIApE8trN8qLGNSiRN9TUoaUZ1cmVu4XnVdd5LQLOXTtyi+vtfUbNnT3iyjzpPqYeKXmvJ+gJGYWw==}
+ cpu: [ppc64]
+ os: [linux]
- /@szmarczak/http-timer@5.0.1:
- resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==}
- engines: {node: '>=14.16'}
- dependencies:
- defer-to-connect: 2.0.1
- dev: true
+ '@rollup/rollup-linux-riscv64-gnu@4.39.0':
+ resolution: {integrity: sha512-t7j5Zhr7S4bBtksT73bO6c3Qa2AV/HqiGlj9+KB3gNF5upcVkx+HLgxTm8DK4OkzsOYqbdqbLKwvGMhylJCPhQ==}
+ cpu: [riscv64]
+ os: [linux]
- /@tootallnate/once@2.0.0:
- resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==}
- engines: {node: '>= 10'}
- dev: true
+ '@rollup/rollup-linux-riscv64-gnu@4.61.0':
+ resolution: {integrity: sha512-RbrzcD3aJ1k3UbtMRRBNwojdVVyXjuVAFTfn/xPa6EEl6GE9Sm/akPgFTb9aAC9pMKGJ6CtWxaGrqWcabH+ySg==}
+ cpu: [riscv64]
+ os: [linux]
- /@tufjs/canonical-json@1.0.0:
- resolution: {integrity: sha512-QTnf++uxunWvG2z3UFNzAoQPHxnSXOwtaI3iJ+AohhV+5vONuArPjJE7aPXPVXfXJsqrVbZBu9b81AJoSd09IQ==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dev: true
+ '@rollup/rollup-linux-riscv64-musl@4.39.0':
+ resolution: {integrity: sha512-m6cwI86IvQ7M93MQ2RF5SP8tUjD39Y7rjb1qjHgYh28uAPVU8+k/xYWvxRO3/tBN2pZkSMa5RjnPuUIbrwVxeA==}
+ cpu: [riscv64]
+ os: [linux]
- /@tufjs/models@1.0.4:
- resolution: {integrity: sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dependencies:
- '@tufjs/canonical-json': 1.0.0
- minimatch: 9.0.3
- dev: true
+ '@rollup/rollup-linux-riscv64-musl@4.61.0':
+ resolution: {integrity: sha512-ZF+onDsBso8PJf1XaG9lB+O9RnBpKGnY6OrzC4CSHrtC1jb6jWLTKK4bRqdoCXHd22gyr2hiYmEAm8Wns/BOCw==}
+ cpu: [riscv64]
+ os: [linux]
- /@types/chai-subset@1.3.5:
- resolution: {integrity: sha512-c2mPnw+xHtXDoHmdtcCXGwyLMiauiAyxWMzhGpqHC4nqI/Y5G2XhTampslK2rb59kpcuHon03UH8W6iYUzw88A==}
- dependencies:
- '@types/chai': 4.3.14
- dev: true
+ '@rollup/rollup-linux-s390x-gnu@4.39.0':
+ resolution: {integrity: sha512-iRDJd2ebMunnk2rsSBYlsptCyuINvxUfGwOUldjv5M4tpa93K8tFMeYGpNk2+Nxl+OBJnBzy2/JCscGeO507kA==}
+ cpu: [s390x]
+ os: [linux]
- /@types/chai@4.3.14:
- resolution: {integrity: sha512-Wj71sXE4Q4AkGdG9Tvq1u/fquNz9EdG4LIJMwVVII7ashjD/8cf8fyIfJAjRr6YcsXnSE8cOGQPq1gqeR8z+3w==}
- dev: true
+ '@rollup/rollup-linux-s390x-gnu@4.61.0':
+ resolution: {integrity: sha512-Atk0aSIk5Zx2Wuh9dgRQgLP0Koc8hOeYpbWryMXyk8G8/HmPkwPPkMqIIDhrXHHYqfUzSJA/I7IWSBv8xSmRBA==}
+ cpu: [s390x]
+ os: [linux]
- /@types/estree@1.0.5:
- resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
- dev: true
+ '@rollup/rollup-linux-x64-gnu@4.39.0':
+ resolution: {integrity: sha512-t9jqYw27R6Lx0XKfEFe5vUeEJ5pF3SGIM6gTfONSMb7DuG6z6wfj2yjcoZxHg129veTqU7+wOhY6GX8wmf90dA==}
+ cpu: [x64]
+ os: [linux]
- /@types/http-cache-semantics@4.0.4:
- resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==}
- dev: true
+ '@rollup/rollup-linux-x64-gnu@4.61.0':
+ resolution: {integrity: sha512-0uMOcf3eZ5K+K4cYHkdxShFMPlPXCOdfDFEFn9dNYAEEd2cVvmOfH7zFgRVoDgmtQ1m9k5q7qfrHzyMAubKYUA==}
+ cpu: [x64]
+ os: [linux]
- /@types/minimist@1.2.5:
- resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==}
- dev: true
+ '@rollup/rollup-linux-x64-musl@4.39.0':
+ resolution: {integrity: sha512-ThFdkrFDP55AIsIZDKSBWEt/JcWlCzydbZHinZ0F/r1h83qbGeenCt/G/wG2O0reuENDD2tawfAj2s8VK7Bugg==}
+ cpu: [x64]
+ os: [linux]
- /@types/node@12.20.55:
- resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==}
- dev: true
+ '@rollup/rollup-linux-x64-musl@4.61.0':
+ resolution: {integrity: sha512-mvFtE4A/t/7hRJ7X8Ozmu8FsIkAUat2nzl12pgU337BRmq87AQUJztwHz2Zv5/tjo9/C95E66CK03SI/ToEDJw==}
+ cpu: [x64]
+ os: [linux]
- /@types/node@18.19.26:
- resolution: {integrity: sha512-+wiMJsIwLOYCvUqSdKTrfkS8mpTp+MPINe6+Np4TAGFWWRWiBQ5kSq9nZGCSPkzx9mvT+uEukzpX4MOSCydcvw==}
- dependencies:
- undici-types: 5.26.5
- dev: true
+ '@rollup/rollup-openbsd-x64@4.61.0':
+ resolution: {integrity: sha512-z9b9+aTxvt8n2rNltMPvyaUfB8NJ+CVyOrGK/MdIKHx7B+lXmZpm/XbRsU7Rpf3fRqJ2uS6mBJiJveCtq8LHDg==}
+ cpu: [x64]
+ os: [openbsd]
- /@types/normalize-package-data@2.4.4:
- resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==}
- dev: true
+ '@rollup/rollup-openharmony-arm64@4.61.0':
+ resolution: {integrity: sha512-jXaXFqKMehsOc+g8R6oo33RRC6w07G9jDBxAE5eAKX7mOcCbZloYIPNhfG9Wl+P9O9IWHFO4OJgPi1Ml2qkt7w==}
+ cpu: [arm64]
+ os: [openharmony]
- /@types/semver-utils@1.1.3:
- resolution: {integrity: sha512-T+YwkslhsM+CeuhYUxyAjWm7mJ5am/K10UX40RuA6k6Lc7eGtq8iY2xOzy7Vq0GOqhl/xZl5l2FwURZMTPTUww==}
- dev: true
+ '@rollup/rollup-win32-arm64-msvc@4.39.0':
+ resolution: {integrity: sha512-jDrLm6yUtbOg2TYB3sBF3acUnAwsIksEYjLeHL+TJv9jg+TmTwdyjnDex27jqEMakNKf3RwwPahDIt7QXCSqRQ==}
+ cpu: [arm64]
+ os: [win32]
- /@types/semver@7.5.8:
- resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==}
- dev: true
+ '@rollup/rollup-win32-arm64-msvc@4.61.0':
+ resolution: {integrity: sha512-OXNWVFocS2IA4+QplhTZZ2a+8hPZR7T8KuozsNmJKK8y7cp83StHvGksfHzPG3wczWTczyWHVQuqeiTUbjiyBg==}
+ cpu: [arm64]
+ os: [win32]
- /@types/ws@8.5.10:
- resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==}
- dependencies:
- '@types/node': 18.19.26
- dev: true
+ '@rollup/rollup-win32-ia32-msvc@4.39.0':
+ resolution: {integrity: sha512-6w9uMuza+LbLCVoNKL5FSLE7yvYkq9laSd09bwS0tMjkwXrmib/4KmoJcrKhLWHvw19mwU+33ndC69T7weNNjQ==}
+ cpu: [ia32]
+ os: [win32]
- /@vitest/expect@0.34.6:
- resolution: {integrity: sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw==}
- dependencies:
- '@vitest/spy': 0.34.6
- '@vitest/utils': 0.34.6
- chai: 4.4.1
- dev: true
+ '@rollup/rollup-win32-ia32-msvc@4.61.0':
+ resolution: {integrity: sha512-AlAbNtBO637LxSldqV43z0FfXoGfl2TW1DgAg/bs7aQswFbDewz2SJm3BUhiGfbOVtW571xbc9p+REdxhyN/Eg==}
+ cpu: [ia32]
+ os: [win32]
- /@vitest/runner@0.34.6:
- resolution: {integrity: sha512-1CUQgtJSLF47NnhN+F9X2ycxUP0kLHQ/JWvNHbeBfwW8CzEGgeskzNnHDyv1ieKTltuR6sdIHV+nmR6kPxQqzQ==}
- dependencies:
- '@vitest/utils': 0.34.6
- p-limit: 4.0.0
- pathe: 1.1.2
- dev: true
+ '@rollup/rollup-win32-x64-gnu@4.61.0':
+ resolution: {integrity: sha512-QRSrQXyJ1M4tjNXdR0/G/IgV6lzfQQJYBjlWIEYkY2Xs86DRl/iEpQ4blMDjJxSl7n19eDKKXMg0AmuBVYy8pQ==}
+ cpu: [x64]
+ os: [win32]
- /@vitest/snapshot@0.34.6:
- resolution: {integrity: sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w==}
- dependencies:
- magic-string: 0.30.8
- pathe: 1.1.2
- pretty-format: 29.7.0
- dev: true
+ '@rollup/rollup-win32-x64-msvc@4.39.0':
+ resolution: {integrity: sha512-yAkUOkIKZlK5dl7u6dg897doBgLXmUHhIINM2c+sND3DZwnrdQkkSiDh7N75Ll4mM4dxSkYfXqU9fW3lLkMFug==}
+ cpu: [x64]
+ os: [win32]
- /@vitest/spy@0.34.6:
- resolution: {integrity: sha512-xaCvneSaeBw/cz8ySmF7ZwGvL0lBjfvqc1LpQ/vcdHEvpLn3Ff1vAvjw+CoGn0802l++5L/pxb7whwcWAw+DUQ==}
- dependencies:
- tinyspy: 2.2.1
- dev: true
+ '@rollup/rollup-win32-x64-msvc@4.61.0':
+ resolution: {integrity: sha512-tkuFxhvKO/HlGd0VsINF6vHSYH8AF8W0TcNxKDK6JZmrehngFj78pToc8iemtnvwilDjs2G/qSzYFhe9U8q+fw==}
+ cpu: [x64]
+ os: [win32]
- /@vitest/utils@0.34.6:
- resolution: {integrity: sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==}
- dependencies:
- diff-sequences: 29.6.3
- loupe: 2.3.7
- pretty-format: 29.7.0
- dev: true
+ '@standard-schema/spec@1.1.0':
+ resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
- /@zkochan/retry@0.2.0:
- resolution: {integrity: sha512-WhB+2B/ZPlW2Xy/kMJBrMbqecWXcbDDgn0K0wKBAgO2OlBTz1iLJrRWduo+DGGn0Akvz1Lu4Xvls7dJojximWw==}
- engines: {node: '>=10'}
- dev: true
+ '@stylistic/eslint-plugin-js@1.8.1':
+ resolution: {integrity: sha512-c5c2C8Mos5tTQd+NWpqwEu7VT6SSRooAguFPMj1cp2RkTYl1ynKoXo8MWy3k4rkbzoeYHrqC2UlUzsroAN7wtQ==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ peerDependencies:
+ eslint: '>=8.40.0'
- /@zkochan/rimraf@2.1.3:
- resolution: {integrity: sha512-mCfR3gylCzPC+iqdxEA6z5SxJeOgzgbwmyxanKriIne5qZLswDe/M43aD3p5MNzwzXRhbZg/OX+MpES6Zk1a6A==}
- engines: {node: '>=12.10'}
- dependencies:
- rimraf: 3.0.2
- dev: true
+ '@stylistic/eslint-plugin-ts@1.8.1':
+ resolution: {integrity: sha512-/q1m+ZuO1JHfiSF16EATFzv7XSJkc5W6DocfvH5o9oB6WWYFMF77fVoBWnKT3wGptPOc2hkRupRKhmeFROdfWA==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ peerDependencies:
+ eslint: '>=8.40.0'
- /abbrev@1.1.1:
- resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
- dev: true
+ '@tybys/wasm-util@0.10.2':
+ resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==}
- /acorn-walk@8.3.2:
- resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==}
- engines: {node: '>=0.4.0'}
- dev: true
+ '@types/chai@5.2.3':
+ resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==}
- /acorn@8.11.3:
- resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==}
- engines: {node: '>=0.4.0'}
- hasBin: true
- dev: true
+ '@types/deep-eql@4.0.2':
+ resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
- /agent-base@6.0.2:
- resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
- engines: {node: '>= 6.0.0'}
- dependencies:
- debug: 4.3.4
- transitivePeerDependencies:
- - supports-color
- dev: true
+ '@types/eslint@8.56.12':
+ resolution: {integrity: sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==}
- /agentkeepalive@4.5.0:
- resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==}
- engines: {node: '>= 8.0.0'}
- dependencies:
- humanize-ms: 1.2.1
- dev: true
+ '@types/estree@1.0.7':
+ resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==}
- /aggregate-error@3.1.0:
- resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==}
- engines: {node: '>=8'}
- dependencies:
- clean-stack: 2.2.0
- indent-string: 4.0.0
- dev: true
+ '@types/estree@1.0.9':
+ resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==}
- /ansi-align@3.0.1:
- resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==}
- dependencies:
- string-width: 4.2.3
- dev: true
+ '@types/json-schema@7.0.15':
+ resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
- /ansi-colors@4.1.3:
- resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==}
- engines: {node: '>=6'}
- dev: true
+ '@types/node@12.20.55':
+ resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==}
- /ansi-regex@5.0.1:
- resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
- engines: {node: '>=8'}
- dev: true
+ '@types/node@20.19.41':
+ resolution: {integrity: sha512-ECymXOukMnOoVkC2bb1Vc/w/836DXncOg5m8Xj1RH7xSHZJWNYY6Zh7EH477vcnD5egKNNfy2RpNOmuChhFPgQ==}
- /ansi-regex@6.0.1:
- resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==}
- engines: {node: '>=12'}
- dev: true
+ '@types/semver@7.7.0':
+ resolution: {integrity: sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==}
- /ansi-styles@3.2.1:
- resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
- engines: {node: '>=4'}
- dependencies:
- color-convert: 1.9.3
- dev: true
+ '@typescript-eslint/eslint-plugin@6.21.0':
+ resolution: {integrity: sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ peerDependencies:
+ '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha
+ eslint: ^7.0.0 || ^8.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
- /ansi-styles@4.3.0:
- resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
- engines: {node: '>=8'}
- dependencies:
- color-convert: 2.0.1
- dev: true
+ '@typescript-eslint/eslint-plugin@7.18.0':
+ resolution: {integrity: sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==}
+ engines: {node: ^18.18.0 || >=20.0.0}
+ peerDependencies:
+ '@typescript-eslint/parser': ^7.0.0
+ eslint: ^8.56.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
- /ansi-styles@5.2.0:
- resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
- engines: {node: '>=10'}
- dev: true
+ '@typescript-eslint/parser@6.21.0':
+ resolution: {integrity: sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ peerDependencies:
+ eslint: ^7.0.0 || ^8.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
- /ansi-styles@6.2.1:
- resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
- engines: {node: '>=12'}
- dev: true
+ '@typescript-eslint/parser@7.18.0':
+ resolution: {integrity: sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==}
+ engines: {node: ^18.18.0 || >=20.0.0}
+ peerDependencies:
+ eslint: ^8.56.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
- /any-promise@1.3.0:
- resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
- dev: true
+ '@typescript-eslint/scope-manager@6.21.0':
+ resolution: {integrity: sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==}
+ engines: {node: ^16.0.0 || >=18.0.0}
- /anymatch@3.1.3:
- resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
- engines: {node: '>= 8'}
- dependencies:
- normalize-path: 3.0.0
- picomatch: 2.3.1
- dev: true
+ '@typescript-eslint/scope-manager@7.18.0':
+ resolution: {integrity: sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==}
+ engines: {node: ^18.18.0 || >=20.0.0}
- /aproba@2.0.0:
- resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==}
- dev: true
+ '@typescript-eslint/type-utils@6.21.0':
+ resolution: {integrity: sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ peerDependencies:
+ eslint: ^7.0.0 || ^8.0.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
- /are-we-there-yet@3.0.1:
- resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==}
- engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
- dependencies:
- delegates: 1.0.0
- readable-stream: 3.6.2
- dev: true
+ '@typescript-eslint/type-utils@7.18.0':
+ resolution: {integrity: sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==}
+ engines: {node: ^18.18.0 || >=20.0.0}
+ peerDependencies:
+ eslint: ^8.56.0
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
- /argparse@1.0.10:
- resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
- dependencies:
- sprintf-js: 1.0.3
- dev: true
+ '@typescript-eslint/types@6.21.0':
+ resolution: {integrity: sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==}
+ engines: {node: ^16.0.0 || >=18.0.0}
- /argparse@2.0.1:
- resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
- dev: true
+ '@typescript-eslint/types@7.18.0':
+ resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==}
+ engines: {node: ^18.18.0 || >=20.0.0}
- /arity-n@1.0.4:
- resolution: {integrity: sha512-fExL2kFDC1Q2DUOx3whE/9KoN66IzkY4b4zUHUBFM1ojEYjZZYDcUW3bek/ufGionX9giIKDC5redH2IlGqcQQ==}
- dev: true
+ '@typescript-eslint/typescript-estree@6.21.0':
+ resolution: {integrity: sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
- /array-buffer-byte-length@1.0.1:
- resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.7
- is-array-buffer: 3.0.4
- dev: true
+ '@typescript-eslint/typescript-estree@7.18.0':
+ resolution: {integrity: sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==}
+ engines: {node: ^18.18.0 || >=20.0.0}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
- /array-last@1.3.0:
- resolution: {integrity: sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==}
- engines: {node: '>=0.10.0'}
- dependencies:
- is-number: 4.0.0
- dev: true
+ '@typescript-eslint/utils@6.21.0':
+ resolution: {integrity: sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==}
+ engines: {node: ^16.0.0 || >=18.0.0}
+ peerDependencies:
+ eslint: ^7.0.0 || ^8.0.0
- /array-union@2.1.0:
- resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
- engines: {node: '>=8'}
- dev: true
-
- /array.prototype.flat@1.3.2:
- resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.7
- define-properties: 1.2.1
- es-abstract: 1.23.3
- es-shim-unscopables: 1.0.2
- dev: true
-
- /arraybuffer.prototype.slice@1.0.3:
- resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==}
- engines: {node: '>= 0.4'}
- dependencies:
- array-buffer-byte-length: 1.0.1
- call-bind: 1.0.7
- define-properties: 1.2.1
- es-abstract: 1.23.3
- es-errors: 1.3.0
- get-intrinsic: 1.2.4
- is-array-buffer: 3.0.4
- is-shared-array-buffer: 1.0.3
- dev: true
-
- /arrify@1.0.1:
- resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==}
- engines: {node: '>=0.10.0'}
- dev: true
+ '@typescript-eslint/utils@7.18.0':
+ resolution: {integrity: sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==}
+ engines: {node: ^18.18.0 || >=20.0.0}
+ peerDependencies:
+ eslint: ^8.56.0
- /assertion-error@1.1.0:
- resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==}
- dev: true
+ '@typescript-eslint/visitor-keys@6.21.0':
+ resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==}
+ engines: {node: ^16.0.0 || >=18.0.0}
- /available-typed-arrays@1.0.7:
- resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
- engines: {node: '>= 0.4'}
- dependencies:
- possible-typed-array-names: 1.0.0
- dev: true
+ '@typescript-eslint/visitor-keys@7.18.0':
+ resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==}
+ engines: {node: ^18.18.0 || >=20.0.0}
- /babylon@6.18.0:
- resolution: {integrity: sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==}
- hasBin: true
- dev: true
+ '@ungap/structured-clone@1.3.0':
+ resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
+ deprecated: Potential CWE-502 - Update to 1.3.1 or higher
- /balanced-match@1.0.2:
- resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
- dev: true
+ '@vitest/expect@4.1.8':
+ resolution: {integrity: sha512-h3nDO677RDLEGlBxyQ5CW8RlMThSKSRLUePLOx09gNIWRL40edgA1GCZSZgf1W55MFAG6/Sw14KeaAnqv0NKdQ==}
- /better-path-resolve@1.0.0:
- resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==}
- engines: {node: '>=4'}
- dependencies:
- is-windows: 1.0.2
- dev: true
+ '@vitest/mocker@4.1.8':
+ resolution: {integrity: sha512-LEiN/xe4OSIbKe9HQIp5OC24agGD9J5CnmMgsLohVVoOPWL9a2sBoR6VBx43jQZb7Kr1l4RCuyCJzcAa0+dojw==}
+ peerDependencies:
+ msw: ^2.4.9
+ vite: ^6.0.0 || ^7.0.0 || ^8.0.0
+ peerDependenciesMeta:
+ msw:
+ optional: true
+ vite:
+ optional: true
- /binary-extensions@2.3.0:
- resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
- engines: {node: '>=8'}
- dev: true
+ '@vitest/pretty-format@4.1.8':
+ resolution: {integrity: sha512-9GasEBxpZ1VYIpqHf/0+YGg121uSNwCKOJqIrTwWP/TB7DmFCiaBpNl3aPZzoLWfWkuqhbH8vJIVobZkvdo2cA==}
- /bole@5.0.11:
- resolution: {integrity: sha512-KB0Ye0iMAW5BnNbnLfMSQcnI186hKUzE2fpkZWqcxsoTR7eqzlTidSOMYPHJOn/yR7VGH7uSZp37qH9q2Et0zQ==}
- dependencies:
- fast-safe-stringify: 2.1.1
- individual: 3.0.0
- dev: true
+ '@vitest/runner@4.1.8':
+ resolution: {integrity: sha512-EmVxeBAfMJvycdjd6Hm+RbFBbA9fKvo0Kx37hNpBYoYeavH3RNsBXWDooR1mgD52dCrxIIuP7UotpfiwOikvcg==}
- /boxen@7.1.1:
- resolution: {integrity: sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==}
- engines: {node: '>=14.16'}
- dependencies:
- ansi-align: 3.0.1
- camelcase: 7.0.1
- chalk: 5.3.0
- cli-boxes: 3.0.0
- string-width: 5.1.2
- type-fest: 2.19.0
- widest-line: 4.0.1
- wrap-ansi: 8.1.0
- dev: true
+ '@vitest/snapshot@4.1.8':
+ resolution: {integrity: sha512-acfZboRmAIf05DEKcBQy33VXojFJjtUdLyo7oOmV9kebb2xdU01UknNiPuPZoJZQyO7DF0gZdTGTpeAzET9QPQ==}
- /brace-expansion@1.1.11:
- resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
- dependencies:
- balanced-match: 1.0.2
- concat-map: 0.0.1
- dev: true
+ '@vitest/spy@4.1.8':
+ resolution: {integrity: sha512-6EevtBp6OZOPF7bmz36HrGMeP3txgVSrgebWxHOafDXGkhIzfXK14f8KF6MuFfgXXUeHxmpD3BQxkV00/3s5mA==}
- /brace-expansion@2.0.1:
- resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
- dependencies:
- balanced-match: 1.0.2
- dev: true
+ '@vitest/utils@4.1.8':
+ resolution: {integrity: sha512-uOJamYALNhfJ6iolExyQM40yIQwDqYnkKtQ5VCiSe17E33H0aQ/u+1GlRuz4LZBk6Mm3sg90G9hEbmEt37C1Zg==}
- /braces@3.0.2:
- resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
- engines: {node: '>=8'}
- dependencies:
- fill-range: 7.0.1
- dev: true
+ acorn-jsx@5.3.2:
+ resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
+ peerDependencies:
+ acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
- /breakword@1.0.6:
- resolution: {integrity: sha512-yjxDAYyK/pBvws9H4xKYpLDpYKEH6CzrBPAuXq3x18I+c/2MkVtT3qAr7Oloi6Dss9qNhPVueAAVU1CSeNDIXw==}
- dependencies:
- wcwidth: 1.0.1
- dev: true
+ acorn@8.15.0:
+ resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
- /buffer-from@1.1.2:
- resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
- dev: true
+ ajv@6.12.6:
+ resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
- /bufferutil@4.0.8:
- resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==}
- engines: {node: '>=6.14.2'}
- requiresBuild: true
- dependencies:
- node-gyp-build: 4.8.0
- dev: false
+ ansi-regex@5.0.1:
+ resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
+ engines: {node: '>=8'}
- /builtins@5.0.1:
- resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==}
- dependencies:
- semver: 7.6.0
- dev: true
+ ansi-styles@4.3.0:
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+ engines: {node: '>=8'}
- /bundle-require@4.0.2(esbuild@0.17.19):
- resolution: {integrity: sha512-jwzPOChofl67PSTW2SGubV9HBQAhhR2i6nskiOThauo9dzwDUgOWQScFVaJkjEfYX+UXiD+LEx8EblQMc2wIag==}
- engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
- peerDependencies:
- esbuild: '>=0.17'
- dependencies:
- esbuild: 0.17.19
- load-tsconfig: 0.2.5
- dev: true
+ any-promise@1.3.0:
+ resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
- /cac@6.7.14:
- resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
- engines: {node: '>=8'}
- dev: true
-
- /cacache@16.1.3:
- resolution: {integrity: sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==}
- engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
- dependencies:
- '@npmcli/fs': 2.1.2
- '@npmcli/move-file': 2.0.1
- chownr: 2.0.0
- fs-minipass: 2.1.0
- glob: 8.1.0
- infer-owner: 1.0.4
- lru-cache: 7.18.3
- minipass: 3.3.6
- minipass-collect: 1.0.2
- minipass-flush: 1.0.5
- minipass-pipeline: 1.2.4
- mkdirp: 1.0.4
- p-map: 4.0.0
- promise-inflight: 1.0.1
- rimraf: 3.0.2
- ssri: 9.0.1
- tar: 6.2.1
- unique-filename: 2.0.1
- transitivePeerDependencies:
- - bluebird
- dev: true
-
- /cacache@17.1.4:
- resolution: {integrity: sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dependencies:
- '@npmcli/fs': 3.1.0
- fs-minipass: 3.0.3
- glob: 10.3.10
- lru-cache: 7.18.3
- minipass: 7.0.4
- minipass-collect: 1.0.2
- minipass-flush: 1.0.5
- minipass-pipeline: 1.2.4
- p-map: 4.0.0
- ssri: 10.0.5
- tar: 6.2.1
- unique-filename: 3.0.0
- dev: true
-
- /cacheable-lookup@7.0.0:
- resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==}
- engines: {node: '>=14.16'}
- dev: true
+ argparse@1.0.10:
+ resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
- /cacheable-request@10.2.14:
- resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==}
- engines: {node: '>=14.16'}
- dependencies:
- '@types/http-cache-semantics': 4.0.4
- get-stream: 6.0.1
- http-cache-semantics: 4.1.1
- keyv: 4.5.4
- mimic-response: 4.0.0
- normalize-url: 8.0.1
- responselike: 3.0.0
- dev: true
-
- /call-bind@1.0.7:
- resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==}
- engines: {node: '>= 0.4'}
- dependencies:
- es-define-property: 1.0.0
- es-errors: 1.3.0
- function-bind: 1.1.2
- get-intrinsic: 1.2.4
- set-function-length: 1.2.2
- dev: true
-
- /camelcase-keys@6.2.2:
- resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==}
- engines: {node: '>=8'}
- dependencies:
- camelcase: 5.3.1
- map-obj: 4.3.0
- quick-lru: 4.0.1
- dev: true
+ argparse@2.0.1:
+ resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
- /camelcase@5.3.1:
- resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
- engines: {node: '>=6'}
- dev: true
+ array-union@2.1.0:
+ resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
+ engines: {node: '>=8'}
- /camelcase@7.0.1:
- resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==}
- engines: {node: '>=14.16'}
- dev: true
+ assertion-error@2.0.1:
+ resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
+ engines: {node: '>=12'}
- /chai@4.4.1:
- resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==}
- engines: {node: '>=4'}
- dependencies:
- assertion-error: 1.1.0
- check-error: 1.0.3
- deep-eql: 4.1.3
- get-func-name: 2.0.2
- loupe: 2.3.7
- pathval: 1.1.1
- type-detect: 4.0.8
- dev: true
-
- /chalk@2.4.2:
- resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
- engines: {node: '>=4'}
- dependencies:
- ansi-styles: 3.2.1
- escape-string-regexp: 1.0.5
- supports-color: 5.5.0
- dev: true
+ balanced-match@1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
- /chalk@4.1.2:
- resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
- engines: {node: '>=10'}
- dependencies:
- ansi-styles: 4.3.0
- supports-color: 7.2.0
- dev: true
+ balanced-match@4.0.4:
+ resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==}
+ engines: {node: 18 || 20 || >=22}
- /chalk@5.3.0:
- resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==}
- engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
- dev: true
+ better-path-resolve@1.0.0:
+ resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==}
+ engines: {node: '>=4'}
- /changeset@0.2.6:
- resolution: {integrity: sha512-d21ym9zLPOKMVhIa8ulJo5IV3QR2NNdK6BWuwg48qJA0XSQaMeDjo1UGThcTn7YDmU08j3UpKyFNvb3zplk8mw==}
- dependencies:
- udc: 1.0.1
- underscore: 1.13.6
- dev: true
+ brace-expansion@1.1.14:
+ resolution: {integrity: sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==}
- /chardet@0.7.0:
- resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==}
- dev: true
+ brace-expansion@2.1.1:
+ resolution: {integrity: sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==}
- /check-error@1.0.3:
- resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==}
- dependencies:
- get-func-name: 2.0.2
- dev: true
+ brace-expansion@5.0.6:
+ resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==}
+ engines: {node: 18 || 20 || >=22}
- /chokidar@3.6.0:
- resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
- engines: {node: '>= 8.10.0'}
- dependencies:
- anymatch: 3.1.3
- braces: 3.0.2
- glob-parent: 5.1.2
- is-binary-path: 2.1.0
- is-glob: 4.0.3
- normalize-path: 3.0.0
- readdirp: 3.6.0
- optionalDependencies:
- fsevents: 2.3.3
- dev: true
+ braces@3.0.3:
+ resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
+ engines: {node: '>=8'}
- /chownr@2.0.0:
- resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==}
- engines: {node: '>=10'}
- dev: true
+ bundle-require@5.1.0:
+ resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+ peerDependencies:
+ esbuild: '>=0.18'
- /ci-info@3.9.0:
- resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==}
+ cac@6.7.14:
+ resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
engines: {node: '>=8'}
- dev: true
- /clean-stack@2.2.0:
- resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==}
+ callsites@3.1.0:
+ resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
engines: {node: '>=6'}
- dev: true
- /cli-boxes@3.0.0:
- resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==}
- engines: {node: '>=10'}
- dev: true
+ chai@6.2.2:
+ resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==}
+ engines: {node: '>=18'}
- /cli-table3@0.6.4:
- resolution: {integrity: sha512-Lm3L0p+/npIQWNIiyF/nAn7T5dnOwR3xNTHXYEBFBFVPXzCVNZ5lqEC/1eo/EVfpDsQ1I+TX4ORPQgp+UI0CRw==}
- engines: {node: 10.* || >= 12.*}
- dependencies:
- string-width: 4.2.3
- optionalDependencies:
- '@colors/colors': 1.5.0
- dev: true
+ chalk@4.1.2:
+ resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
+ engines: {node: '>=10'}
- /cliui@6.0.0:
- resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==}
- dependencies:
- string-width: 4.2.3
- strip-ansi: 6.0.1
- wrap-ansi: 6.2.0
- dev: true
+ chalk@5.6.2:
+ resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==}
+ engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
- /cliui@8.0.1:
- resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
- engines: {node: '>=12'}
- dependencies:
- string-width: 4.2.3
- strip-ansi: 6.0.1
- wrap-ansi: 7.0.0
- dev: true
+ changeset@0.2.6:
+ resolution: {integrity: sha512-d21ym9zLPOKMVhIa8ulJo5IV3QR2NNdK6BWuwg48qJA0XSQaMeDjo1UGThcTn7YDmU08j3UpKyFNvb3zplk8mw==}
- /clone@1.0.4:
- resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==}
- engines: {node: '>=0.8'}
- requiresBuild: true
- dev: true
+ chokidar@4.0.3:
+ resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
+ engines: {node: '>= 14.16.0'}
- /color-convert@1.9.3:
- resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
- dependencies:
- color-name: 1.1.3
- dev: true
+ chownr@3.0.0:
+ resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==}
+ engines: {node: '>=18'}
- /color-convert@2.0.1:
+ color-convert@2.0.1:
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
engines: {node: '>=7.0.0'}
- dependencies:
- color-name: 1.1.4
- dev: true
-
- /color-name@1.1.3:
- resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
- dev: true
- /color-name@1.1.4:
+ color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
- dev: true
- /color-support@1.1.3:
- resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==}
- hasBin: true
- dev: true
-
- /commander@10.0.1:
- resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==}
- engines: {node: '>=14'}
- dev: true
-
- /commander@4.1.1:
+ commander@4.1.1:
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
engines: {node: '>= 6'}
- dev: true
- /compose-function@3.0.3:
- resolution: {integrity: sha512-xzhzTJ5eC+gmIzvZq+C3kCJHsp9os6tJkrigDRZclyGtOKINbZtE8n1Tzmeh32jW+BUDPbvZpibwvJHBLGMVwg==}
- dependencies:
- arity-n: 1.0.4
- dev: true
+ compare-versions@6.1.1:
+ resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==}
- /concat-map@0.0.1:
+ concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
- dev: true
-
- /config-chain@1.1.13:
- resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==}
- dependencies:
- ini: 1.3.8
- proto-list: 1.2.4
- dev: true
- /configstore@6.0.0:
- resolution: {integrity: sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==}
- engines: {node: '>=12'}
- dependencies:
- dot-prop: 6.0.1
- graceful-fs: 4.2.11
- unique-string: 3.0.0
- write-file-atomic: 3.0.3
- xdg-basedir: 5.1.0
- dev: true
+ confbox@0.1.8:
+ resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==}
- /console-control-strings@1.1.0:
- resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==}
- dev: true
+ consola@3.4.0:
+ resolution: {integrity: sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA==}
+ engines: {node: ^14.18.0 || >=16.10.0}
- /cross-spawn@5.1.0:
- resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==}
- dependencies:
- lru-cache: 4.1.5
- shebang-command: 1.2.0
- which: 1.3.1
- dev: true
+ convert-source-map@2.0.0:
+ resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
- /cross-spawn@7.0.3:
- resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
+ cross-spawn@7.0.6:
+ resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
- dependencies:
- path-key: 3.1.1
- shebang-command: 2.0.0
- which: 2.0.2
- dev: true
- /crypto-random-string@2.0.0:
- resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==}
- engines: {node: '>=8'}
- dev: true
+ debug@4.4.0:
+ resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
- /crypto-random-string@4.0.0:
- resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==}
- engines: {node: '>=12'}
- dependencies:
- type-fest: 1.4.0
- dev: true
+ debug@4.4.3:
+ resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ deep-is@0.1.4:
+ resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
+
+ dir-glob@3.0.1:
+ resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
+ engines: {node: '>=8'}
- /csv-generate@3.4.3:
- resolution: {integrity: sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw==}
- dev: true
+ dockerfile-ast@0.7.1:
+ resolution: {integrity: sha512-oX/A4I0EhSkGqrFv0YuvPkBUSYp1XiY8O8zAKc8Djglx8ocz+JfOr8gP0ryRMC2myqvDLagmnZaU9ot1vG2ijw==}
- /csv-parse@4.16.3:
- resolution: {integrity: sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg==}
- dev: true
+ doctrine@3.0.0:
+ resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
+ engines: {node: '>=6.0.0'}
- /csv-stringify@5.6.5:
- resolution: {integrity: sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A==}
- dev: true
+ dotenv@16.6.1:
+ resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==}
+ engines: {node: '>=12'}
- /csv@5.5.3:
- resolution: {integrity: sha512-QTaY0XjjhTQOdguARF0lGKm5/mEq9PD9/VhZZegHDIBq2tQwgNpHc3dneD4mGo2iJs+fTKv5Bp0fZ+BRuY3Z0g==}
- engines: {node: '>= 0.1.90'}
- dependencies:
- csv-generate: 3.4.3
- csv-parse: 4.16.3
- csv-stringify: 5.6.5
- stream-transform: 2.1.3
- dev: true
+ e2b@2.28.0:
+ resolution: {integrity: sha512-ptvySeKFFwz+bJbGIT6WGRkLr+Xwo1/oicf82cFuMepPXdRd3CrJoZ8FGnu+XWHRSJlOKBfCWENrDZmg4oKTtQ==}
+ engines: {node: '>=20.18.1'}
- /data-uri-to-buffer@3.0.1:
- resolution: {integrity: sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==}
- engines: {node: '>= 6'}
- dev: true
+ es-module-lexer@2.1.0:
+ resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==}
- /data-view-buffer@1.0.1:
- resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.7
- es-errors: 1.3.0
- is-data-view: 1.0.1
- dev: true
+ esbuild@0.27.2:
+ resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==}
+ engines: {node: '>=18'}
+ hasBin: true
- /data-view-byte-length@1.0.1:
- resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.7
- es-errors: 1.3.0
- is-data-view: 1.0.1
- dev: true
+ esbuild@0.27.7:
+ resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==}
+ engines: {node: '>=18'}
+ hasBin: true
- /data-view-byte-offset@1.0.0:
- resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.7
- es-errors: 1.3.0
- is-data-view: 1.0.1
- dev: true
+ escape-string-regexp@4.0.0:
+ resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
+ engines: {node: '>=10'}
- /debug@4.3.4:
- resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
- engines: {node: '>=6.0'}
+ eslint-plugin-unused-imports@3.2.0:
+ resolution: {integrity: sha512-6uXyn6xdINEpxE1MtDjxQsyXB37lfyO2yKGVVgtD7WEWQGORSOZjgrD6hBhvGv4/SO+TOlS+UnC6JppRqbuwGQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
- supports-color: '*'
+ '@typescript-eslint/eslint-plugin': 6 - 7
+ eslint: '8'
peerDependenciesMeta:
- supports-color:
+ '@typescript-eslint/eslint-plugin':
optional: true
- dependencies:
- ms: 2.1.2
- dev: true
- /decamelize-keys@1.1.1:
- resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==}
- engines: {node: '>=0.10.0'}
- dependencies:
- decamelize: 1.2.0
- map-obj: 1.0.1
- dev: true
+ eslint-rule-composer@0.3.0:
+ resolution: {integrity: sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==}
+ engines: {node: '>=4.0.0'}
- /decamelize@1.2.0:
- resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==}
- engines: {node: '>=0.10.0'}
- dev: true
+ eslint-scope@7.2.2:
+ resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
- /decompress-response@6.0.0:
- resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
- engines: {node: '>=10'}
- dependencies:
- mimic-response: 3.1.0
- dev: true
+ eslint-visitor-keys@3.4.3:
+ resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
- /deep-eql@4.1.3:
- resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==}
- engines: {node: '>=6'}
- dependencies:
- type-detect: 4.0.8
- dev: true
+ eslint@8.57.1:
+ resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options.
+ hasBin: true
- /deep-extend@0.6.0:
- resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==}
- engines: {node: '>=4.0.0'}
- dev: true
+ espree@9.6.1:
+ resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
- /deep-freeze@0.0.1:
- resolution: {integrity: sha512-Z+z8HiAvsGwmjqlphnHW5oz6yWlOwu6EQfFTjmeTWlDeda3FS2yv3jhq35TX/ewmsnqB+RX2IdsIOyjJCQN5tg==}
- dev: true
+ esprima@4.0.1:
+ resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
+ engines: {node: '>=4'}
+ hasBin: true
- /defaults@1.0.4:
- resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==}
- requiresBuild: true
- dependencies:
- clone: 1.0.4
- dev: true
+ esquery@1.6.0:
+ resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==}
+ engines: {node: '>=0.10'}
- /defer-to-connect@2.0.1:
- resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==}
- engines: {node: '>=10'}
- dev: true
+ esrecurse@4.3.0:
+ resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
+ engines: {node: '>=4.0'}
- /define-data-property@1.1.4:
- resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
- engines: {node: '>= 0.4'}
- dependencies:
- es-define-property: 1.0.0
- es-errors: 1.3.0
- gopd: 1.0.1
- dev: true
+ estraverse@5.3.0:
+ resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
+ engines: {node: '>=4.0'}
- /define-properties@1.2.1:
- resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
- engines: {node: '>= 0.4'}
- dependencies:
- define-data-property: 1.1.4
- has-property-descriptors: 1.0.2
- object-keys: 1.1.1
- dev: true
+ estree-walker@3.0.3:
+ resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
- /delegates@1.0.0:
- resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==}
- dev: true
+ esutils@2.0.3:
+ resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
+ engines: {node: '>=0.10.0'}
- /detect-indent@6.1.0:
- resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==}
- engines: {node: '>=8'}
- dev: true
+ expect-type@1.3.0:
+ resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==}
+ engines: {node: '>=12.0.0'}
- /diff-sequences@29.6.3:
- resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
- dev: true
+ extendable-error@0.1.7:
+ resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==}
- /dir-glob@3.0.1:
- resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
- engines: {node: '>=8'}
- dependencies:
- path-type: 4.0.0
- dev: true
+ fast-deep-equal@3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
- /dot-prop@6.0.1:
- resolution: {integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==}
- engines: {node: '>=10'}
- dependencies:
- is-obj: 2.0.0
- dev: true
+ fast-glob@3.3.3:
+ resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
+ engines: {node: '>=8.6.0'}
- /dotenv@16.4.5:
- resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==}
- engines: {node: '>=12'}
- dev: true
+ fast-json-stable-stringify@2.1.0:
+ resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
- /e2b@0.16.0:
- resolution: {integrity: sha512-ZPZ9tmbTduX8HVDKTVoA87vhZ9xIL3AZ3m1poh+9yErcF87GJuOJm6o4ZUrup8kP1rV2simWK7IMZMg/0U3pPQ==}
- engines: {node: '>=18'}
- dependencies:
- isomorphic-ws: 5.0.0(ws@8.16.0)
- normalize-path: 3.0.0
- openapi-typescript-fetch: 1.1.3
- path-browserify: 1.0.1
- platform: 1.3.6
- ws: 8.16.0(bufferutil@4.0.8)(utf-8-validate@6.0.3)
- optionalDependencies:
- bufferutil: 4.0.8
- utf-8-validate: 6.0.3
- dev: false
+ fast-levenshtein@2.0.6:
+ resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
- /eastasianwidth@0.2.0:
- resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
- dev: true
+ fastq@1.19.0:
+ resolution: {integrity: sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==}
- /easy-table@1.2.0:
- resolution: {integrity: sha512-OFzVOv03YpvtcWGe5AayU5G2hgybsg3iqA6drU8UaoZyB9jLGMTrz9+asnLp/E+6qPh88yEI1gvyZFZ41dmgww==}
- dependencies:
- ansi-regex: 5.0.1
- optionalDependencies:
- wcwidth: 1.0.1
- dev: true
+ fd-package-json@2.0.0:
+ resolution: {integrity: sha512-jKmm9YtsNXN789RS/0mSzOC1NUq9mkVd65vbSSVsKdjGvYXBuE4oWe2QOEoFeRmJg+lPuZxpmrfFclNhoRMneQ==}
+
+ fdir@6.5.0:
+ resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
+ engines: {node: '>=12.0.0'}
+ peerDependencies:
+ picomatch: ^3 || ^4
+ peerDependenciesMeta:
+ picomatch:
+ optional: true
+
+ file-entry-cache@6.0.1:
+ resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
+ engines: {node: ^10.12.0 || >=12.0.0}
- /emoji-regex@8.0.0:
- resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
- dev: true
+ fill-range@7.1.1:
+ resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
+ engines: {node: '>=8'}
- /emoji-regex@9.2.2:
- resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
- dev: true
+ find-up@4.1.0:
+ resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
+ engines: {node: '>=8'}
- /encode-registry@3.0.1:
- resolution: {integrity: sha512-6qOwkl1g0fv0DN3Y3ggr2EaZXN71aoAqPp3p/pVaWSBSIo+YjLOWN61Fva43oVyQNPf7kgm8lkudzlzojwE2jw==}
+ find-up@5.0.0:
+ resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
engines: {node: '>=10'}
- dependencies:
- mem: 8.1.1
- dev: true
- /encoding@0.1.13:
- resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==}
- requiresBuild: true
- dependencies:
- iconv-lite: 0.6.3
- dev: true
- optional: true
+ fix-dts-default-cjs-exports@1.0.1:
+ resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==}
- /enquirer@2.4.1:
- resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==}
- engines: {node: '>=8.6'}
- dependencies:
- ansi-colors: 4.1.3
- strip-ansi: 6.0.1
- dev: true
+ flat-cache@3.2.0:
+ resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==}
+ engines: {node: ^10.12.0 || >=12.0.0}
- /env-paths@2.2.1:
- resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
- engines: {node: '>=6'}
- dev: true
-
- /err-code@2.0.3:
- resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==}
- dev: true
-
- /error-ex@1.3.2:
- resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
- dependencies:
- is-arrayish: 0.2.1
- dev: true
-
- /es-abstract@1.23.3:
- resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==}
- engines: {node: '>= 0.4'}
- dependencies:
- array-buffer-byte-length: 1.0.1
- arraybuffer.prototype.slice: 1.0.3
- available-typed-arrays: 1.0.7
- call-bind: 1.0.7
- data-view-buffer: 1.0.1
- data-view-byte-length: 1.0.1
- data-view-byte-offset: 1.0.0
- es-define-property: 1.0.0
- es-errors: 1.3.0
- es-object-atoms: 1.0.0
- es-set-tostringtag: 2.0.3
- es-to-primitive: 1.2.1
- function.prototype.name: 1.1.6
- get-intrinsic: 1.2.4
- get-symbol-description: 1.0.2
- globalthis: 1.0.3
- gopd: 1.0.1
- has-property-descriptors: 1.0.2
- has-proto: 1.0.3
- has-symbols: 1.0.3
- hasown: 2.0.2
- internal-slot: 1.0.7
- is-array-buffer: 3.0.4
- is-callable: 1.2.7
- is-data-view: 1.0.1
- is-negative-zero: 2.0.3
- is-regex: 1.1.4
- is-shared-array-buffer: 1.0.3
- is-string: 1.0.7
- is-typed-array: 1.1.13
- is-weakref: 1.0.2
- object-inspect: 1.13.1
- object-keys: 1.1.1
- object.assign: 4.1.5
- regexp.prototype.flags: 1.5.2
- safe-array-concat: 1.1.2
- safe-regex-test: 1.0.3
- string.prototype.trim: 1.2.9
- string.prototype.trimend: 1.0.8
- string.prototype.trimstart: 1.0.8
- typed-array-buffer: 1.0.2
- typed-array-byte-length: 1.0.1
- typed-array-byte-offset: 1.0.2
- typed-array-length: 1.0.6
- unbox-primitive: 1.0.2
- which-typed-array: 1.1.15
- dev: true
-
- /es-define-property@1.0.0:
- resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==}
- engines: {node: '>= 0.4'}
- dependencies:
- get-intrinsic: 1.2.4
- dev: true
-
- /es-errors@1.3.0:
- resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
- engines: {node: '>= 0.4'}
- dev: true
-
- /es-object-atoms@1.0.0:
- resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==}
- engines: {node: '>= 0.4'}
- dependencies:
- es-errors: 1.3.0
- dev: true
-
- /es-set-tostringtag@2.0.3:
- resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==}
- engines: {node: '>= 0.4'}
- dependencies:
- get-intrinsic: 1.2.4
- has-tostringtag: 1.0.2
- hasown: 2.0.2
- dev: true
-
- /es-shim-unscopables@1.0.2:
- resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==}
- dependencies:
- hasown: 2.0.2
- dev: true
-
- /es-to-primitive@1.2.1:
- resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==}
- engines: {node: '>= 0.4'}
- dependencies:
- is-callable: 1.2.7
- is-date-object: 1.0.5
- is-symbol: 1.0.4
- dev: true
-
- /esbuild@0.17.19:
- resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==}
- engines: {node: '>=12'}
- hasBin: true
- requiresBuild: true
- optionalDependencies:
- '@esbuild/android-arm': 0.17.19
- '@esbuild/android-arm64': 0.17.19
- '@esbuild/android-x64': 0.17.19
- '@esbuild/darwin-arm64': 0.17.19
- '@esbuild/darwin-x64': 0.17.19
- '@esbuild/freebsd-arm64': 0.17.19
- '@esbuild/freebsd-x64': 0.17.19
- '@esbuild/linux-arm': 0.17.19
- '@esbuild/linux-arm64': 0.17.19
- '@esbuild/linux-ia32': 0.17.19
- '@esbuild/linux-loong64': 0.17.19
- '@esbuild/linux-mips64el': 0.17.19
- '@esbuild/linux-ppc64': 0.17.19
- '@esbuild/linux-riscv64': 0.17.19
- '@esbuild/linux-s390x': 0.17.19
- '@esbuild/linux-x64': 0.17.19
- '@esbuild/netbsd-x64': 0.17.19
- '@esbuild/openbsd-x64': 0.17.19
- '@esbuild/sunos-x64': 0.17.19
- '@esbuild/win32-arm64': 0.17.19
- '@esbuild/win32-ia32': 0.17.19
- '@esbuild/win32-x64': 0.17.19
- dev: true
-
- /esbuild@0.20.2:
- resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==}
- engines: {node: '>=12'}
- hasBin: true
- requiresBuild: true
- optionalDependencies:
- '@esbuild/aix-ppc64': 0.20.2
- '@esbuild/android-arm': 0.20.2
- '@esbuild/android-arm64': 0.20.2
- '@esbuild/android-x64': 0.20.2
- '@esbuild/darwin-arm64': 0.20.2
- '@esbuild/darwin-x64': 0.20.2
- '@esbuild/freebsd-arm64': 0.20.2
- '@esbuild/freebsd-x64': 0.20.2
- '@esbuild/linux-arm': 0.20.2
- '@esbuild/linux-arm64': 0.20.2
- '@esbuild/linux-ia32': 0.20.2
- '@esbuild/linux-loong64': 0.20.2
- '@esbuild/linux-mips64el': 0.20.2
- '@esbuild/linux-ppc64': 0.20.2
- '@esbuild/linux-riscv64': 0.20.2
- '@esbuild/linux-s390x': 0.20.2
- '@esbuild/linux-x64': 0.20.2
- '@esbuild/netbsd-x64': 0.20.2
- '@esbuild/openbsd-x64': 0.20.2
- '@esbuild/sunos-x64': 0.20.2
- '@esbuild/win32-arm64': 0.20.2
- '@esbuild/win32-ia32': 0.20.2
- '@esbuild/win32-x64': 0.20.2
- dev: true
-
- /escalade@3.1.2:
- resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==}
- engines: {node: '>=6'}
- dev: true
+ flatted@3.3.3:
+ resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==}
- /escape-goat@4.0.0:
- resolution: {integrity: sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==}
- engines: {node: '>=12'}
- dev: true
+ foreground-child@3.3.1:
+ resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
+ engines: {node: '>=14'}
- /escape-string-regexp@1.0.5:
- resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
- engines: {node: '>=0.8.0'}
- dev: true
+ formatly@0.3.0:
+ resolution: {integrity: sha512-9XNj/o4wrRFyhSMJOvsuyMwy8aUfBaZ1VrqHVfohyXf0Sw0e+yfKG+xZaY3arGCOMdwFsqObtzVOc1gU9KiT9w==}
+ engines: {node: '>=18.3.0'}
+ hasBin: true
- /esprima@4.0.1:
- resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
- engines: {node: '>=4'}
+ fs-extra@7.0.1:
+ resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==}
+ engines: {node: '>=6 <7 || >=8'}
+
+ fs-extra@8.1.0:
+ resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==}
+ engines: {node: '>=6 <7 || >=8'}
+
+ fs.realpath@1.0.0:
+ resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ glob-parent@5.1.2:
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+ engines: {node: '>= 6'}
+
+ glob-parent@6.0.2:
+ resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
+ engines: {node: '>=10.13.0'}
+
+ glob@11.1.0:
+ resolution: {integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==}
+ engines: {node: 20 || >=22}
+ deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
hasBin: true
- dev: true
- /execa@5.1.1:
- resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
+ glob@7.2.3:
+ resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
+ deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
+
+ globals@13.24.0:
+ resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==}
+ engines: {node: '>=8'}
+
+ globby@11.1.0:
+ resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
engines: {node: '>=10'}
- dependencies:
- cross-spawn: 7.0.3
- get-stream: 6.0.1
- human-signals: 2.1.0
- is-stream: 2.0.1
- merge-stream: 2.0.0
- npm-run-path: 4.0.1
- onetime: 5.1.2
- signal-exit: 3.0.7
- strip-final-newline: 2.0.0
- dev: true
-
- /exponential-backoff@3.1.1:
- resolution: {integrity: sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==}
- dev: true
-
- /extendable-error@0.1.7:
- resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==}
- dev: true
- /external-editor@3.1.0:
- resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==}
+ graceful-fs@4.2.11:
+ resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+
+ graphemer@1.4.0:
+ resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
+
+ has-flag@4.0.0:
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+ engines: {node: '>=8'}
+
+ ignore@5.3.1:
+ resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==}
+ engines: {node: '>= 4'}
+
+ import-fresh@3.3.1:
+ resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==}
+ engines: {node: '>=6'}
+
+ imurmurhash@0.1.4:
+ resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
+ engines: {node: '>=0.8.19'}
+
+ inflight@1.0.6:
+ resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
+ deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
+
+ inherits@2.0.4:
+ resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+
+ is-extglob@2.1.1:
+ resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+ engines: {node: '>=0.10.0'}
+
+ is-glob@4.0.3:
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+ engines: {node: '>=0.10.0'}
+
+ is-number@7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+
+ is-path-inside@3.0.3:
+ resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
+ engines: {node: '>=8'}
+
+ is-subdir@1.2.0:
+ resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==}
engines: {node: '>=4'}
- dependencies:
- chardet: 0.7.0
- iconv-lite: 0.4.24
- tmp: 0.0.33
- dev: true
- /fast-glob@3.3.2:
- resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
- engines: {node: '>=8.6.0'}
- dependencies:
- '@nodelib/fs.stat': 2.0.5
- '@nodelib/fs.walk': 1.2.8
- glob-parent: 5.1.2
- merge2: 1.4.1
- micromatch: 4.0.5
- dev: true
+ is-windows@1.0.2:
+ resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==}
+ engines: {node: '>=0.10.0'}
+
+ isexe@2.0.0:
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
- /fast-memoize@2.5.2:
- resolution: {integrity: sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==}
- dev: true
+ jackspeak@4.2.3:
+ resolution: {integrity: sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==}
+ engines: {node: 20 || >=22}
- /fast-safe-stringify@2.1.1:
- resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==}
- dev: true
+ jiti@2.7.0:
+ resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==}
+ hasBin: true
- /fastq@1.17.1:
- resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
- dependencies:
- reusify: 1.0.4
- dev: true
+ joycon@3.1.1:
+ resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==}
+ engines: {node: '>=10'}
+
+ js-yaml@3.14.2:
+ resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==}
+ hasBin: true
+
+ js-yaml@4.1.1:
+ resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==}
+ hasBin: true
+
+ json-buffer@3.0.1:
+ resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
+
+ json-schema-traverse@0.4.1:
+ resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+
+ json-stable-stringify-without-jsonify@1.0.1:
+ resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
+
+ jsonfile@4.0.0:
+ resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==}
+
+ keyv@4.5.4:
+ resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
+
+ knip@5.88.1:
+ resolution: {integrity: sha512-tpy5o7zu1MjawVkLPuahymVJekYY3kYjvzcoInhIchgePxTlo+api90tBv2KfhAIe5uXh+mez1tAfmbv8/TiZg==}
+ engines: {node: '>=18.18.0'}
+ hasBin: true
+ peerDependencies:
+ '@types/node': '>=18'
+ typescript: '>=5.0.4 <7'
+
+ levn@0.4.1:
+ resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
+ engines: {node: '>= 0.8.0'}
+
+ lilconfig@3.1.2:
+ resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==}
+ engines: {node: '>=14'}
+
+ lines-and-columns@1.2.4:
+ resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
+
+ load-tsconfig@0.2.5:
+ resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
+ locate-path@5.0.0:
+ resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
+ engines: {node: '>=8'}
+
+ locate-path@6.0.0:
+ resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
+ engines: {node: '>=10'}
+
+ lodash.merge@4.6.2:
+ resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
+
+ lru-cache@11.5.1:
+ resolution: {integrity: sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==}
+ engines: {node: 20 || >=22}
+
+ lru-cache@6.0.0:
+ resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
+ engines: {node: '>=10'}
+
+ magic-string@0.30.21:
+ resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
+
+ merge2@1.4.1:
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+ engines: {node: '>= 8'}
+
+ micromatch@4.0.8:
+ resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
+ engines: {node: '>=8.6'}
+
+ minimatch@10.2.5:
+ resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==}
+ engines: {node: 18 || 20 || >=22}
+
+ minimatch@3.1.2:
+ resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
+
+ minimatch@9.0.3:
+ resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ minimatch@9.0.9:
+ resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ minimist@1.2.8:
+ resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+
+ minipass@7.1.3:
+ resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ minizlib@3.1.0:
+ resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==}
+ engines: {node: '>= 18'}
+
+ mlly@1.8.0:
+ resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==}
+
+ ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
+ mz@2.7.0:
+ resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
+
+ nanoid@3.3.12:
+ resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ natural-compare@1.4.0:
+ resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
+
+ npm-check-updates@17.1.18:
+ resolution: {integrity: sha512-bkUy2g4v1i+3FeUf5fXMLbxmV95eG4/sS7lYE32GrUeVgQRfQEk39gpskksFunyaxQgTIdrvYbnuNbO/pSUSqw==}
+ engines: {node: ^18.18.0 || >=20.0.0, npm: '>=8.12.1'}
+ hasBin: true
+
+ object-assign@4.1.1:
+ resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
+ engines: {node: '>=0.10.0'}
+
+ obug@2.1.1:
+ resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==}
+
+ once@1.4.0:
+ resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
+
+ openapi-fetch@0.14.1:
+ resolution: {integrity: sha512-l7RarRHxlEZYjMLd/PR0slfMVse2/vvIAGm75/F7J6MlQ8/b9uUQmUF2kCPrQhJqMXSxmYWObVgeYXbFYzZR+A==}
+
+ openapi-typescript-helpers@0.0.15:
+ resolution: {integrity: sha512-opyTPaunsklCBpTK8JGef6mfPhLSnyy5a0IN9vKtx3+4aExf+KxEqYwIy3hqkedXIB97u357uLMJsOnm3GVjsw==}
+
+ optionator@0.9.4:
+ resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
+ engines: {node: '>= 0.8.0'}
+
+ oxc-resolver@11.20.0:
+ resolution: {integrity: sha512-CblytBiV/a/ZXY34dsVU2NxhIOxMXst8CvDCtyBelVITgd7PLrKzbEbA6oKLdPjvDKDzCiW48qzmzZ+mYaqn+g==}
+
+ p-filter@2.1.0:
+ resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==}
+ engines: {node: '>=8'}
+
+ p-limit@2.3.0:
+ resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
+ engines: {node: '>=6'}
+
+ p-limit@3.1.0:
+ resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
+ engines: {node: '>=10'}
+
+ p-locate@4.1.0:
+ resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
+ engines: {node: '>=8'}
- /fetch-blob@2.1.2:
- resolution: {integrity: sha512-YKqtUDwqLyfyMnmbw8XD6Q8j9i/HggKtPEI+pZ1+8bvheBu78biSmNaXWusx1TauGqtUUGx/cBb1mKdq2rLYow==}
- engines: {node: ^10.17.0 || >=12.3.0}
+ p-locate@5.0.0:
+ resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
+ engines: {node: '>=10'}
+
+ p-map@2.1.0:
+ resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==}
+ engines: {node: '>=6'}
+
+ p-try@2.2.0:
+ resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
+ engines: {node: '>=6'}
+
+ package-json-from-dist@1.0.1:
+ resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
+
+ parent-module@1.0.1:
+ resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
+ engines: {node: '>=6'}
+
+ path-exists@4.0.0:
+ resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
+ engines: {node: '>=8'}
+
+ path-is-absolute@1.0.1:
+ resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
+ engines: {node: '>=0.10.0'}
+
+ path-key@3.1.1:
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+ engines: {node: '>=8'}
+
+ path-scurry@2.0.2:
+ resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==}
+ engines: {node: 18 || 20 || >=22}
+
+ path-type@4.0.0:
+ resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
+ engines: {node: '>=8'}
+
+ pathe@2.0.3:
+ resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ picomatch@2.3.2:
+ resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==}
+ engines: {node: '>=8.6'}
+
+ picomatch@4.0.4:
+ resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==}
+ engines: {node: '>=12'}
+
+ pify@4.0.1:
+ resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==}
+ engines: {node: '>=6'}
+
+ pirates@4.0.6:
+ resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
+ engines: {node: '>= 6'}
+
+ pkg-types@1.3.1:
+ resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==}
+
+ platform@1.3.6:
+ resolution: {integrity: sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==}
+
+ postcss-load-config@6.0.1:
+ resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==}
+ engines: {node: '>= 18'}
peerDependencies:
- domexception: '*'
+ jiti: '>=1.21.0'
+ postcss: '>=8.0.9'
+ tsx: ^4.8.1
+ yaml: ^2.4.2
peerDependenciesMeta:
- domexception:
+ jiti:
+ optional: true
+ postcss:
optional: true
- dev: true
+ tsx:
+ optional: true
+ yaml:
+ optional: true
+
+ postcss@8.5.15:
+ resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ prelude-ls@1.2.1:
+ resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
+ engines: {node: '>= 0.8.0'}
+
+ prettier@3.6.2:
+ resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==}
+ engines: {node: '>=14'}
+ hasBin: true
+
+ punycode@2.3.1:
+ resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
+ engines: {node: '>=6'}
+
+ queue-microtask@1.2.3:
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+
+ read-yaml-file@1.1.0:
+ resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==}
+ engines: {node: '>=6'}
- /fill-range@7.0.1:
- resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
+ readdirp@4.1.1:
+ resolution: {integrity: sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==}
+ engines: {node: '>= 14.18.0'}
+
+ resolve-from@4.0.0:
+ resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
+ engines: {node: '>=4'}
+
+ resolve-from@5.0.0:
+ resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
engines: {node: '>=8'}
- dependencies:
- to-regex-range: 5.0.1
- dev: true
- /filter-iterator@0.0.1:
- resolution: {integrity: sha512-v4lhL7Qa8XpbW3LN46CEnmhGk3eHZwxfNl5at20aEkreesht4YKb/Ba3BUIbnPhAC/r3dmu7ABaGk6MAvh2alA==}
- dev: true
+ reusify@1.0.4:
+ resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+
+ rimraf@3.0.2:
+ resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
+ deprecated: Rimraf versions prior to v4 are no longer supported
+ hasBin: true
+
+ rollup@4.39.0:
+ resolution: {integrity: sha512-thI8kNc02yNvnmJp8dr3fNWJ9tCONDhp6TV35X6HkKGGs9E6q7YWCHbe5vKiTa7TAiNcFEmXKj3X/pG2b3ci0g==}
+ engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+ hasBin: true
- /filter-obj@1.1.0:
- resolution: {integrity: sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==}
+ rollup@4.61.0:
+ resolution: {integrity: sha512-T9mWdbWfQtp0B5lv/HX+wrhYsmXRlcWnXXmJbXqKJhlRaoS6KMhq0gpyzW4UJfclcxrEdLnTgjT2NjruLONu0g==}
+ engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+ hasBin: true
+
+ run-parallel@1.2.0:
+ resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+
+ semver@7.6.0:
+ resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ shebang-command@2.0.0:
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+ engines: {node: '>=8'}
+
+ shebang-regex@3.0.0:
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+ engines: {node: '>=8'}
+
+ siginfo@2.0.0:
+ resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
+
+ signal-exit@4.1.0:
+ resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
+ engines: {node: '>=14'}
+
+ slash@3.0.0:
+ resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
+ engines: {node: '>=8'}
+
+ smol-toml@1.6.1:
+ resolution: {integrity: sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==}
+ engines: {node: '>= 18'}
+
+ source-map-js@1.2.1:
+ resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
- dev: true
- /find-up@4.1.0:
- resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
+ source-map@0.7.6:
+ resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==}
+ engines: {node: '>= 12'}
+
+ spawndamnit@3.0.1:
+ resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==}
+
+ sprintf-js@1.0.3:
+ resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
+
+ stackback@0.0.2:
+ resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
+
+ std-env@4.1.0:
+ resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==}
+
+ strip-ansi@6.0.1:
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
engines: {node: '>=8'}
- dependencies:
- locate-path: 5.0.0
- path-exists: 4.0.0
- dev: true
- /find-up@5.0.0:
- resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
+ strip-bom@3.0.0:
+ resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
+ engines: {node: '>=4'}
+
+ strip-json-comments@3.1.1:
+ resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
+ engines: {node: '>=8'}
+
+ strip-json-comments@5.0.3:
+ resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==}
+ engines: {node: '>=14.16'}
+
+ sucrase@3.35.1:
+ resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==}
+ engines: {node: '>=16 || 14 >=14.17'}
+ hasBin: true
+
+ supports-color@7.2.0:
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
+ engines: {node: '>=8'}
+
+ tar@7.5.16:
+ resolution: {integrity: sha512-56adEpPMouktRlBLXiaYFFzZ/3+JXa8P9n7WbR+ibIjtviN55mEaOkiysCnPnWm+7kkui1Dn8J9l+g6zV8731w==}
+ engines: {node: '>=18'}
+
+ text-table@0.2.0:
+ resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
+
+ thenify-all@1.6.0:
+ resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
+ engines: {node: '>=0.8'}
+
+ thenify@3.3.1:
+ resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
+
+ tinybench@2.9.0:
+ resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
+
+ tinyexec@0.3.2:
+ resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==}
+
+ tinyexec@1.2.4:
+ resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==}
+ engines: {node: '>=18'}
+
+ tinyglobby@0.2.15:
+ resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==}
+ engines: {node: '>=12.0.0'}
+
+ tinyglobby@0.2.17:
+ resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==}
+ engines: {node: '>=12.0.0'}
+
+ tinyrainbow@3.1.0:
+ resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==}
+ engines: {node: '>=14.0.0'}
+
+ to-regex-range@5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+
+ tree-kill@1.2.2:
+ resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
+ hasBin: true
+
+ ts-api-utils@1.4.3:
+ resolution: {integrity: sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==}
+ engines: {node: '>=16'}
+ peerDependencies:
+ typescript: '>=4.2.0'
+
+ ts-interface-checker@0.1.13:
+ resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
+
+ tslib@2.8.1:
+ resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+
+ tsup@8.5.1:
+ resolution: {integrity: sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==}
+ engines: {node: '>=18'}
+ hasBin: true
+ peerDependencies:
+ '@microsoft/api-extractor': ^7.36.0
+ '@swc/core': ^1
+ postcss: ^8.4.12
+ typescript: '>=4.5.0'
+ peerDependenciesMeta:
+ '@microsoft/api-extractor':
+ optional: true
+ '@swc/core':
+ optional: true
+ postcss:
+ optional: true
+ typescript:
+ optional: true
+
+ type-check@0.4.0:
+ resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
+ engines: {node: '>= 0.8.0'}
+
+ type-fest@0.20.2:
+ resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
engines: {node: '>=10'}
- dependencies:
- locate-path: 6.0.0
- path-exists: 4.0.0
- dev: true
- /find-yarn-workspace-root2@1.2.16:
- resolution: {integrity: sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==}
- dependencies:
- micromatch: 4.0.5
- pkg-dir: 4.2.0
- dev: true
+ typescript@5.7.3:
+ resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==}
+ engines: {node: '>=14.17'}
+ hasBin: true
- /for-each@0.3.3:
- resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
- dependencies:
- is-callable: 1.2.7
- dev: true
+ udc@1.0.1:
+ resolution: {integrity: sha512-jv+D9de1flsum5QkFtBdjyppCQAdz9kTck/0xST5Vx48T9LL2BYnw0Iw77dSKDQ9KZ/PS3qPO1vfXHDpLZlxcQ==}
+
+ ufo@1.6.1:
+ resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==}
- /foreground-child@3.1.1:
- resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==}
+ unbash@2.2.0:
+ resolution: {integrity: sha512-X2wH19RAPZE3+ldGicOkoj/SIA83OIxcJ6Cuaw23hf8Xc6fQpvZXY0SftE2JgS0QhYLUG4uwodSI3R53keyh7w==}
engines: {node: '>=14'}
- dependencies:
- cross-spawn: 7.0.3
- signal-exit: 4.1.0
- dev: true
- /form-data-encoder@2.1.4:
- resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==}
- engines: {node: '>= 14.17'}
- dev: true
+ underscore@1.13.6:
+ resolution: {integrity: sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==}
- /fp-and-or@0.1.4:
- resolution: {integrity: sha512-+yRYRhpnFPWXSly/6V4Lw9IfOV26uu30kynGJ03PW+MnjOEQe45RZ141QcS0aJehYBYA50GfCDnsRbFJdhssRw==}
- engines: {node: '>=10'}
- dev: true
+ undici-types@6.21.0:
+ resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
- /fs-extra@10.1.0:
- resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==}
- engines: {node: '>=12'}
- dependencies:
- graceful-fs: 4.2.11
- jsonfile: 6.1.0
- universalify: 2.0.1
- dev: true
+ undici@7.27.0:
+ resolution: {integrity: sha512-+t2Z/GwkZQDtu00813aP66ygViGtPHKhhoFZpQKpKrE+9jIgES+Zw+mFNaDWOVRKiuJjuqKHzD3B1sfGg8+ZOQ==}
+ engines: {node: '>=20.18.1'}
- /fs-extra@7.0.1:
- resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==}
- engines: {node: '>=6 <7 || >=8'}
- dependencies:
- graceful-fs: 4.2.11
- jsonfile: 4.0.0
- universalify: 0.1.2
- dev: true
+ universalify@0.1.2:
+ resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
+ engines: {node: '>= 4.0.0'}
- /fs-extra@8.1.0:
- resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==}
- engines: {node: '>=6 <7 || >=8'}
- dependencies:
- graceful-fs: 4.2.11
- jsonfile: 4.0.0
- universalify: 0.1.2
- dev: true
+ uri-js@4.4.1:
+ resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
- /fs-minipass@2.1.0:
- resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==}
+ vite@7.3.2:
+ resolution: {integrity: sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^20.19.0 || >=22.12.0
+ jiti: '>=1.21.0'
+ less: ^4.0.0
+ lightningcss: ^1.21.0
+ 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
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ jiti:
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+ tsx:
+ optional: true
+ yaml:
+ optional: true
+
+ vitest@4.1.8:
+ resolution: {integrity: sha512-flY6ScbCIt9HThs+C5HS7jvGOB560DJtk/Z15IQROTA6zEy49Nh8T/dofWTQL+n3vswqn87sbJNiuqw1SDp5Ig==}
+ engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0}
+ hasBin: true
+ peerDependencies:
+ '@edge-runtime/vm': '*'
+ '@opentelemetry/api': ^1.9.0
+ '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0
+ '@vitest/browser-playwright': 4.1.8
+ '@vitest/browser-preview': 4.1.8
+ '@vitest/browser-webdriverio': 4.1.8
+ '@vitest/coverage-istanbul': 4.1.8
+ '@vitest/coverage-v8': 4.1.8
+ '@vitest/ui': 4.1.8
+ happy-dom: '*'
+ jsdom: '*'
+ vite: ^6.0.0 || ^7.0.0 || ^8.0.0
+ peerDependenciesMeta:
+ '@edge-runtime/vm':
+ optional: true
+ '@opentelemetry/api':
+ optional: true
+ '@types/node':
+ optional: true
+ '@vitest/browser-playwright':
+ optional: true
+ '@vitest/browser-preview':
+ optional: true
+ '@vitest/browser-webdriverio':
+ optional: true
+ '@vitest/coverage-istanbul':
+ optional: true
+ '@vitest/coverage-v8':
+ optional: true
+ '@vitest/ui':
+ optional: true
+ happy-dom:
+ optional: true
+ jsdom:
+ optional: true
+
+ vscode-languageserver-textdocument@1.0.12:
+ resolution: {integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==}
+
+ vscode-languageserver-types@3.18.0:
+ resolution: {integrity: sha512-8TsGPNMIMiiBdkORgRSvLjuiEIiAFtO+KssmYWxQ+uSVvlf7RjK8YKCOjPzZ+YA04jXEV7+7LvkSmHkhpNS99g==}
+
+ walk-up-path@4.0.0:
+ resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==}
+ engines: {node: 20 || >=22}
+
+ which@2.0.2:
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
engines: {node: '>= 8'}
- dependencies:
- minipass: 3.3.6
- dev: true
+ hasBin: true
- /fs-minipass@3.0.3:
- resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dependencies:
- minipass: 7.0.4
- dev: true
+ why-is-node-running@2.3.0:
+ resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
+ engines: {node: '>=8'}
+ hasBin: true
+
+ word-wrap@1.2.5:
+ resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
+ engines: {node: '>=0.10.0'}
+
+ wrappy@1.0.2:
+ resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+
+ yallist@4.0.0:
+ resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
+
+ yallist@5.0.0:
+ resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==}
+ engines: {node: '>=18'}
+
+ yaml@2.9.0:
+ resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==}
+ engines: {node: '>= 14.6'}
+ hasBin: true
+
+ yocto-queue@0.1.0:
+ resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
+ engines: {node: '>=10'}
- /fs.realpath@1.0.0:
- resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
- dev: true
+ zod@4.4.3:
+ resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==}
- /fsevents@2.3.3:
- resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
- engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
- os: [darwin]
- requiresBuild: true
- dev: true
- optional: true
+snapshots:
- /function-bind@1.1.2:
- resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
- dev: true
-
- /function.prototype.name@1.1.6:
- resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.7
- define-properties: 1.2.1
- es-abstract: 1.23.3
- functions-have-names: 1.2.3
- dev: true
-
- /functions-have-names@1.2.3:
- resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
- dev: true
-
- /gauge@4.0.4:
- resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==}
- engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
- dependencies:
- aproba: 2.0.0
- color-support: 1.1.3
- console-control-strings: 1.1.0
- has-unicode: 2.0.1
- signal-exit: 3.0.7
- string-width: 4.2.3
- strip-ansi: 6.0.1
- wide-align: 1.1.5
- dev: true
-
- /get-caller-file@2.0.5:
- resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
- engines: {node: 6.* || 8.* || >= 10.*}
- dev: true
-
- /get-func-name@2.0.2:
- resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==}
- dev: true
-
- /get-intrinsic@1.2.4:
- resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==}
- engines: {node: '>= 0.4'}
- dependencies:
- es-errors: 1.3.0
- function-bind: 1.1.2
- has-proto: 1.0.3
- has-symbols: 1.0.3
- hasown: 2.0.2
- dev: true
-
- /get-stdin@8.0.0:
- resolution: {integrity: sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==}
- engines: {node: '>=10'}
- dev: true
+ '@babel/runtime@7.28.6': {}
- /get-stream@6.0.1:
- resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
- engines: {node: '>=10'}
- dev: true
+ '@bufbuild/protobuf@2.12.0': {}
- /get-symbol-description@1.0.2:
- resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==}
- engines: {node: '>= 0.4'}
+ '@changesets/errors@0.2.0':
dependencies:
- call-bind: 1.0.7
- es-errors: 1.3.0
- get-intrinsic: 1.2.4
- dev: true
+ extendable-error: 0.1.7
- /glob-parent@5.1.2:
- resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
- engines: {node: '>= 6'}
+ '@changesets/git@3.0.4':
dependencies:
- is-glob: 4.0.3
- dev: true
+ '@changesets/errors': 0.2.0
+ '@manypkg/get-packages': 1.1.3
+ is-subdir: 1.2.0
+ micromatch: 4.0.8
+ spawndamnit: 3.0.1
- /glob@10.3.10:
- resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==}
- engines: {node: '>=16 || 14 >=14.17'}
- hasBin: true
+ '@changesets/logger@0.1.1':
dependencies:
- foreground-child: 3.1.1
- jackspeak: 2.3.6
- minimatch: 9.0.3
- minipass: 7.0.4
- path-scurry: 1.10.1
- dev: true
+ picocolors: 1.1.1
- /glob@7.2.3:
- resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
+ '@changesets/parse@0.4.3':
dependencies:
- fs.realpath: 1.0.0
- inflight: 1.0.6
- inherits: 2.0.4
- minimatch: 3.1.2
- once: 1.4.0
- path-is-absolute: 1.0.1
- dev: true
+ '@changesets/types': 6.1.0
+ js-yaml: 4.1.1
- /glob@8.1.0:
- resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==}
- engines: {node: '>=12'}
+ '@changesets/read@0.6.7':
dependencies:
- fs.realpath: 1.0.0
- inflight: 1.0.6
- inherits: 2.0.4
- minimatch: 5.1.6
- once: 1.4.0
- dev: true
+ '@changesets/git': 3.0.4
+ '@changesets/logger': 0.1.1
+ '@changesets/parse': 0.4.3
+ '@changesets/types': 6.1.0
+ fs-extra: 7.0.1
+ p-filter: 2.1.0
+ picocolors: 1.1.1
- /global-dirs@3.0.1:
- resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==}
- engines: {node: '>=10'}
- dependencies:
- ini: 2.0.0
- dev: true
+ '@changesets/types@4.1.0': {}
- /globalthis@1.0.3:
- resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==}
- engines: {node: '>= 0.4'}
- dependencies:
- define-properties: 1.2.1
- dev: true
+ '@changesets/types@6.1.0': {}
- /globby@11.1.0:
- resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
- engines: {node: '>=10'}
+ '@connectrpc/connect-web@2.0.0-rc.3(@bufbuild/protobuf@2.12.0)(@connectrpc/connect@2.0.0-rc.3(@bufbuild/protobuf@2.12.0))':
dependencies:
- array-union: 2.1.0
- dir-glob: 3.0.1
- fast-glob: 3.3.2
- ignore: 5.3.1
- merge2: 1.4.1
- slash: 3.0.0
- dev: true
+ '@bufbuild/protobuf': 2.12.0
+ '@connectrpc/connect': 2.0.0-rc.3(@bufbuild/protobuf@2.12.0)
- /globby@13.2.2:
- resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==}
- engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+ '@connectrpc/connect@2.0.0-rc.3(@bufbuild/protobuf@2.12.0)':
dependencies:
- dir-glob: 3.0.1
- fast-glob: 3.3.2
- ignore: 5.3.1
- merge2: 1.4.1
- slash: 4.0.0
- dev: true
+ '@bufbuild/protobuf': 2.12.0
- /gopd@1.0.1:
- resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
+ '@emnapi/core@1.10.0':
dependencies:
- get-intrinsic: 1.2.4
- dev: true
+ '@emnapi/wasi-threads': 1.2.1
+ tslib: 2.8.1
+ optional: true
- /got@12.6.1:
- resolution: {integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==}
- engines: {node: '>=14.16'}
+ '@emnapi/runtime@1.10.0':
dependencies:
- '@sindresorhus/is': 5.6.0
- '@szmarczak/http-timer': 5.0.1
- cacheable-lookup: 7.0.0
- cacheable-request: 10.2.14
- decompress-response: 6.0.0
- form-data-encoder: 2.1.4
- get-stream: 6.0.1
- http2-wrapper: 2.2.1
- lowercase-keys: 3.0.0
- p-cancelable: 3.0.0
- responselike: 3.0.0
- dev: true
-
- /graceful-fs@4.2.10:
- resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==}
- dev: true
-
- /graceful-fs@4.2.11:
- resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
- dev: true
-
- /grapheme-splitter@1.0.4:
- resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==}
- dev: true
+ tslib: 2.8.1
+ optional: true
- /hard-rejection@2.1.0:
- resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==}
- engines: {node: '>=6'}
- dev: true
+ '@emnapi/wasi-threads@1.2.1':
+ dependencies:
+ tslib: 2.8.1
+ optional: true
- /has-bigints@1.0.2:
- resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==}
- dev: true
+ '@esbuild/aix-ppc64@0.27.2':
+ optional: true
- /has-flag@3.0.0:
- resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
- engines: {node: '>=4'}
- dev: true
+ '@esbuild/aix-ppc64@0.27.7':
+ optional: true
- /has-flag@4.0.0:
- resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
- engines: {node: '>=8'}
- dev: true
+ '@esbuild/android-arm64@0.27.2':
+ optional: true
- /has-own-property@0.1.0:
- resolution: {integrity: sha512-14qdBKoonU99XDhWcFKZTShK+QV47qU97u8zzoVo9cL5TZ3BmBHXogItSt9qJjR0KUMFRhcCW8uGIGl8nkl7Aw==}
- dev: true
+ '@esbuild/android-arm64@0.27.7':
+ optional: true
- /has-property-descriptors@1.0.2:
- resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
- dependencies:
- es-define-property: 1.0.0
- dev: true
+ '@esbuild/android-arm@0.27.2':
+ optional: true
- /has-proto@1.0.3:
- resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==}
- engines: {node: '>= 0.4'}
- dev: true
+ '@esbuild/android-arm@0.27.7':
+ optional: true
- /has-symbols@1.0.3:
- resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
- engines: {node: '>= 0.4'}
- dev: true
+ '@esbuild/android-x64@0.27.2':
+ optional: true
- /has-tostringtag@1.0.2:
- resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
- engines: {node: '>= 0.4'}
- dependencies:
- has-symbols: 1.0.3
- dev: true
+ '@esbuild/android-x64@0.27.7':
+ optional: true
- /has-unicode@2.0.1:
- resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==}
- dev: true
+ '@esbuild/darwin-arm64@0.27.2':
+ optional: true
- /has-yarn@3.0.0:
- resolution: {integrity: sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==}
- engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
- dev: true
+ '@esbuild/darwin-arm64@0.27.7':
+ optional: true
- /hasown@2.0.2:
- resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
- engines: {node: '>= 0.4'}
- dependencies:
- function-bind: 1.1.2
- dev: true
+ '@esbuild/darwin-x64@0.27.2':
+ optional: true
- /hosted-git-info@2.8.9:
- resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==}
- dev: true
+ '@esbuild/darwin-x64@0.27.7':
+ optional: true
- /hosted-git-info@4.1.0:
- resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==}
- engines: {node: '>=10'}
- dependencies:
- lru-cache: 6.0.0
- dev: true
+ '@esbuild/freebsd-arm64@0.27.2':
+ optional: true
- /hosted-git-info@5.2.1:
- resolution: {integrity: sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==}
- engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
- dependencies:
- lru-cache: 7.18.3
- dev: true
+ '@esbuild/freebsd-arm64@0.27.7':
+ optional: true
- /hosted-git-info@6.1.1:
- resolution: {integrity: sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dependencies:
- lru-cache: 7.18.3
- dev: true
+ '@esbuild/freebsd-x64@0.27.2':
+ optional: true
- /http-cache-semantics@4.1.1:
- resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==}
- dev: true
+ '@esbuild/freebsd-x64@0.27.7':
+ optional: true
- /http-proxy-agent@5.0.0:
- resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==}
- engines: {node: '>= 6'}
- dependencies:
- '@tootallnate/once': 2.0.0
- agent-base: 6.0.2
- debug: 4.3.4
- transitivePeerDependencies:
- - supports-color
- dev: true
+ '@esbuild/linux-arm64@0.27.2':
+ optional: true
- /http2-wrapper@2.2.1:
- resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==}
- engines: {node: '>=10.19.0'}
- dependencies:
- quick-lru: 5.1.1
- resolve-alpn: 1.2.1
- dev: true
+ '@esbuild/linux-arm64@0.27.7':
+ optional: true
- /https-proxy-agent@5.0.1:
- resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
- engines: {node: '>= 6'}
- dependencies:
- agent-base: 6.0.2
- debug: 4.3.4
- transitivePeerDependencies:
- - supports-color
- dev: true
+ '@esbuild/linux-arm@0.27.2':
+ optional: true
- /human-id@1.0.2:
- resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==}
- dev: true
+ '@esbuild/linux-arm@0.27.7':
+ optional: true
- /human-signals@2.1.0:
- resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
- engines: {node: '>=10.17.0'}
- dev: true
+ '@esbuild/linux-ia32@0.27.2':
+ optional: true
- /humanize-ms@1.2.1:
- resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==}
- dependencies:
- ms: 2.1.3
- dev: true
+ '@esbuild/linux-ia32@0.27.7':
+ optional: true
- /iconv-lite@0.4.24:
- resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
- engines: {node: '>=0.10.0'}
- dependencies:
- safer-buffer: 2.1.2
- dev: true
+ '@esbuild/linux-loong64@0.27.2':
+ optional: true
- /iconv-lite@0.6.3:
- resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
- engines: {node: '>=0.10.0'}
- requiresBuild: true
- dependencies:
- safer-buffer: 2.1.2
- dev: true
+ '@esbuild/linux-loong64@0.27.7':
optional: true
- /identity-function@1.0.0:
- resolution: {integrity: sha512-kNrgUK0qI+9qLTBidsH85HjDLpZfrrS0ElquKKe/fJFdB3D7VeKdXXEvOPDUHSHOzdZKCAAaQIWWyp0l2yq6pw==}
- dev: true
+ '@esbuild/linux-mips64el@0.27.2':
+ optional: true
- /ignore-walk@6.0.4:
- resolution: {integrity: sha512-t7sv42WkwFkyKbivUCglsQW5YWMskWtbEf4MNKX5u/CCWHKSPzN4FtBQGsQZgCLbxOzpVlcbWVK5KB3auIOjSw==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dependencies:
- minimatch: 9.0.3
- dev: true
+ '@esbuild/linux-mips64el@0.27.7':
+ optional: true
- /ignore@5.3.1:
- resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==}
- engines: {node: '>= 4'}
- dev: true
+ '@esbuild/linux-ppc64@0.27.2':
+ optional: true
- /import-lazy@4.0.0:
- resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==}
- engines: {node: '>=8'}
- dev: true
+ '@esbuild/linux-ppc64@0.27.7':
+ optional: true
- /imurmurhash@0.1.4:
- resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
- engines: {node: '>=0.8.19'}
- dev: true
+ '@esbuild/linux-riscv64@0.27.2':
+ optional: true
- /indent-string@4.0.0:
- resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
- engines: {node: '>=8'}
- dev: true
+ '@esbuild/linux-riscv64@0.27.7':
+ optional: true
- /individual@3.0.0:
- resolution: {integrity: sha512-rUY5vtT748NMRbEMrTNiFfy29BgGZwGXUi2NFUVMWQrogSLzlJvQV9eeMWi+g1aVaQ53tpyLAQtd5x/JH0Nh1g==}
- dev: true
+ '@esbuild/linux-s390x@0.27.2':
+ optional: true
- /infer-owner@1.0.4:
- resolution: {integrity: sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==}
- dev: true
+ '@esbuild/linux-s390x@0.27.7':
+ optional: true
- /inflight@1.0.6:
- resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
- dependencies:
- once: 1.4.0
- wrappy: 1.0.2
- dev: true
+ '@esbuild/linux-x64@0.27.2':
+ optional: true
- /inherits@2.0.4:
- resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
- dev: true
+ '@esbuild/linux-x64@0.27.7':
+ optional: true
- /ini@1.3.8:
- resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
- dev: true
+ '@esbuild/netbsd-arm64@0.27.2':
+ optional: true
- /ini@2.0.0:
- resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==}
- engines: {node: '>=10'}
- dev: true
+ '@esbuild/netbsd-arm64@0.27.7':
+ optional: true
- /ini@4.1.2:
- resolution: {integrity: sha512-AMB1mvwR1pyBFY/nSevUX6y8nJWS63/SzUKD3JyQn97s4xgIdgQPT75IRouIiBAN4yLQBUShNYVW0+UG25daCw==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dev: true
+ '@esbuild/netbsd-x64@0.27.2':
+ optional: true
- /internal-slot@1.0.7:
- resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==}
- engines: {node: '>= 0.4'}
- dependencies:
- es-errors: 1.3.0
- hasown: 2.0.2
- side-channel: 1.0.6
- dev: true
+ '@esbuild/netbsd-x64@0.27.7':
+ optional: true
- /ip-address@9.0.5:
- resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==}
- engines: {node: '>= 12'}
- dependencies:
- jsbn: 1.1.0
- sprintf-js: 1.1.3
- dev: true
+ '@esbuild/openbsd-arm64@0.27.2':
+ optional: true
- /is-array-buffer@3.0.4:
- resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.7
- get-intrinsic: 1.2.4
- dev: true
+ '@esbuild/openbsd-arm64@0.27.7':
+ optional: true
- /is-arrayish@0.2.1:
- resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
- dev: true
+ '@esbuild/openbsd-x64@0.27.2':
+ optional: true
- /is-bigint@1.0.4:
- resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
- dependencies:
- has-bigints: 1.0.2
- dev: true
+ '@esbuild/openbsd-x64@0.27.7':
+ optional: true
- /is-binary-path@2.1.0:
- resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
- engines: {node: '>=8'}
- dependencies:
- binary-extensions: 2.3.0
- dev: true
+ '@esbuild/openharmony-arm64@0.27.2':
+ optional: true
- /is-boolean-object@1.1.2:
- resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.7
- has-tostringtag: 1.0.2
- dev: true
+ '@esbuild/openharmony-arm64@0.27.7':
+ optional: true
- /is-callable@1.2.7:
- resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
- engines: {node: '>= 0.4'}
- dev: true
+ '@esbuild/sunos-x64@0.27.2':
+ optional: true
- /is-ci@3.0.1:
- resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==}
- hasBin: true
- dependencies:
- ci-info: 3.9.0
- dev: true
+ '@esbuild/sunos-x64@0.27.7':
+ optional: true
- /is-core-module@2.13.1:
- resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==}
- dependencies:
- hasown: 2.0.2
- dev: true
+ '@esbuild/win32-arm64@0.27.2':
+ optional: true
- /is-data-view@1.0.1:
- resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==}
- engines: {node: '>= 0.4'}
- dependencies:
- is-typed-array: 1.1.13
- dev: true
+ '@esbuild/win32-arm64@0.27.7':
+ optional: true
- /is-date-object@1.0.5:
- resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==}
- engines: {node: '>= 0.4'}
- dependencies:
- has-tostringtag: 1.0.2
- dev: true
+ '@esbuild/win32-ia32@0.27.2':
+ optional: true
- /is-extglob@2.1.1:
- resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
- engines: {node: '>=0.10.0'}
- dev: true
+ '@esbuild/win32-ia32@0.27.7':
+ optional: true
- /is-fullwidth-code-point@3.0.0:
- resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
- engines: {node: '>=8'}
- dev: true
+ '@esbuild/win32-x64@0.27.2':
+ optional: true
- /is-glob@4.0.3:
- resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
- engines: {node: '>=0.10.0'}
- dependencies:
- is-extglob: 2.1.1
- dev: true
+ '@esbuild/win32-x64@0.27.7':
+ optional: true
- /is-installed-globally@0.4.0:
- resolution: {integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==}
- engines: {node: '>=10'}
+ '@eslint-community/eslint-utils@4.7.0(eslint@8.57.1)':
dependencies:
- global-dirs: 3.0.1
- is-path-inside: 3.0.3
- dev: true
-
- /is-iterable@1.1.1:
- resolution: {integrity: sha512-EdOZCr0NsGE00Pot+x1ZFx9MJK3C6wy91geZpXwvwexDLJvA4nzYyZf7r+EIwSeVsOLDdBz7ATg9NqKTzuNYuQ==}
- engines: {node: '>= 4'}
- dev: true
+ eslint: 8.57.1
+ eslint-visitor-keys: 3.4.3
- /is-lambda@1.0.1:
- resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==}
- dev: true
+ '@eslint-community/regexpp@4.12.1': {}
- /is-negative-zero@2.0.3:
- resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==}
- engines: {node: '>= 0.4'}
- dev: true
-
- /is-npm@6.0.0:
- resolution: {integrity: sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==}
- engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
- dev: true
-
- /is-number-object@1.0.7:
- resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==}
- engines: {node: '>= 0.4'}
+ '@eslint/eslintrc@2.1.4':
dependencies:
- has-tostringtag: 1.0.2
- dev: true
+ ajv: 6.12.6
+ debug: 4.4.0
+ espree: 9.6.1
+ globals: 13.24.0
+ ignore: 5.3.1
+ import-fresh: 3.3.1
+ js-yaml: 4.1.1
+ minimatch: 3.1.2
+ strip-json-comments: 3.1.1
+ transitivePeerDependencies:
+ - supports-color
- /is-number@4.0.0:
- resolution: {integrity: sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==}
- engines: {node: '>=0.10.0'}
- dev: true
+ '@eslint/js@8.57.1': {}
- /is-number@7.0.0:
- resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
- engines: {node: '>=0.12.0'}
- dev: true
+ '@humanwhocodes/config-array@0.13.0':
+ dependencies:
+ '@humanwhocodes/object-schema': 2.0.3
+ debug: 4.4.0
+ minimatch: 3.1.2
+ transitivePeerDependencies:
+ - supports-color
- /is-obj@2.0.0:
- resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==}
- engines: {node: '>=8'}
- dev: true
+ '@humanwhocodes/module-importer@1.0.1': {}
- /is-path-inside@3.0.3:
- resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
- engines: {node: '>=8'}
- dev: true
+ '@humanwhocodes/object-schema@2.0.3': {}
- /is-plain-obj@1.1.0:
- resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==}
- engines: {node: '>=0.10.0'}
- dev: true
+ '@isaacs/cliui@9.0.0': {}
- /is-regex@1.1.4:
- resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==}
- engines: {node: '>= 0.4'}
+ '@isaacs/fs-minipass@4.0.1':
dependencies:
- call-bind: 1.0.7
- has-tostringtag: 1.0.2
- dev: true
+ minipass: 7.1.3
- /is-shared-array-buffer@1.0.3:
- resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==}
- engines: {node: '>= 0.4'}
+ '@jridgewell/gen-mapping@0.3.5':
dependencies:
- call-bind: 1.0.7
- dev: true
+ '@jridgewell/set-array': 1.2.1
+ '@jridgewell/sourcemap-codec': 1.5.5
+ '@jridgewell/trace-mapping': 0.3.25
- /is-stream@2.0.1:
- resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
- engines: {node: '>=8'}
- dev: true
+ '@jridgewell/resolve-uri@3.1.2': {}
- /is-string@1.0.7:
- resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==}
- engines: {node: '>= 0.4'}
- dependencies:
- has-tostringtag: 1.0.2
- dev: true
+ '@jridgewell/set-array@1.2.1': {}
- /is-subdir@1.2.0:
- resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==}
- engines: {node: '>=4'}
- dependencies:
- better-path-resolve: 1.0.0
- dev: true
+ '@jridgewell/sourcemap-codec@1.5.5': {}
- /is-symbol@1.0.4:
- resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==}
- engines: {node: '>= 0.4'}
+ '@jridgewell/trace-mapping@0.3.25':
dependencies:
- has-symbols: 1.0.3
- dev: true
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.5.5
- /is-typed-array@1.1.13:
- resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==}
- engines: {node: '>= 0.4'}
+ '@manypkg/find-root@1.1.0':
dependencies:
- which-typed-array: 1.1.15
- dev: true
-
- /is-typedarray@1.0.0:
- resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==}
- dev: true
+ '@babel/runtime': 7.28.6
+ '@types/node': 12.20.55
+ find-up: 4.1.0
+ fs-extra: 8.1.0
- /is-weakref@1.0.2:
- resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==}
+ '@manypkg/get-packages@1.1.3':
dependencies:
- call-bind: 1.0.7
- dev: true
-
- /is-windows@1.0.2:
- resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==}
- engines: {node: '>=0.10.0'}
- dev: true
-
- /is-yarn-global@0.4.1:
- resolution: {integrity: sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==}
- engines: {node: '>=12'}
- dev: true
-
- /isarray@2.0.5:
- resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
- dev: true
+ '@babel/runtime': 7.28.6
+ '@changesets/types': 4.1.0
+ '@manypkg/find-root': 1.1.0
+ fs-extra: 8.1.0
+ globby: 11.1.0
+ read-yaml-file: 1.1.0
- /isexe@2.0.0:
- resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
- dev: true
+ '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)':
+ dependencies:
+ '@emnapi/core': 1.10.0
+ '@emnapi/runtime': 1.10.0
+ '@tybys/wasm-util': 0.10.2
+ optional: true
- /isomorphic-ws@5.0.0(ws@8.16.0):
- resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==}
- peerDependencies:
- ws: '*'
+ '@nodelib/fs.scandir@2.1.5':
dependencies:
- ws: 8.16.0(bufferutil@4.0.8)(utf-8-validate@6.0.3)
- dev: false
+ '@nodelib/fs.stat': 2.0.5
+ run-parallel: 1.2.0
- /iterable-lookahead@1.0.0:
- resolution: {integrity: sha512-hJnEP2Xk4+44DDwJqUQGdXal5VbyeWLaPyDl2AQc242Zr7iqz4DgpQOrEzglWVMGHMDCkguLHEKxd1+rOsmgSQ==}
- engines: {node: '>=4'}
- dev: true
+ '@nodelib/fs.stat@2.0.5': {}
- /jackspeak@2.3.6:
- resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==}
- engines: {node: '>=14'}
+ '@nodelib/fs.walk@1.2.8':
dependencies:
- '@isaacs/cliui': 8.0.2
- optionalDependencies:
- '@pkgjs/parseargs': 0.11.0
- dev: true
+ '@nodelib/fs.scandir': 2.1.5
+ fastq: 1.19.0
- /jiti@1.21.0:
- resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==}
- hasBin: true
- dev: true
+ '@oxc-resolver/binding-android-arm-eabi@11.20.0':
+ optional: true
- /jju@1.4.0:
- resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==}
- dev: true
+ '@oxc-resolver/binding-android-arm64@11.20.0':
+ optional: true
- /joycon@3.1.1:
- resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==}
- engines: {node: '>=10'}
- dev: true
+ '@oxc-resolver/binding-darwin-arm64@11.20.0':
+ optional: true
- /js-tokens@4.0.0:
- resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
- dev: true
+ '@oxc-resolver/binding-darwin-x64@11.20.0':
+ optional: true
- /js-yaml@3.14.1:
- resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==}
- hasBin: true
- dependencies:
- argparse: 1.0.10
- esprima: 4.0.1
- dev: true
+ '@oxc-resolver/binding-freebsd-x64@11.20.0':
+ optional: true
- /js-yaml@4.1.0:
- resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
- hasBin: true
- dependencies:
- argparse: 2.0.1
- dev: true
+ '@oxc-resolver/binding-linux-arm-gnueabihf@11.20.0':
+ optional: true
- /jsbn@1.1.0:
- resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==}
- dev: true
+ '@oxc-resolver/binding-linux-arm-musleabihf@11.20.0':
+ optional: true
- /json-buffer@3.0.1:
- resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
- dev: true
+ '@oxc-resolver/binding-linux-arm64-gnu@11.20.0':
+ optional: true
- /json-parse-even-better-errors@2.3.1:
- resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
- dev: true
+ '@oxc-resolver/binding-linux-arm64-musl@11.20.0':
+ optional: true
- /json-parse-even-better-errors@3.0.1:
- resolution: {integrity: sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dev: true
+ '@oxc-resolver/binding-linux-ppc64-gnu@11.20.0':
+ optional: true
- /json-parse-helpfulerror@1.0.3:
- resolution: {integrity: sha512-XgP0FGR77+QhUxjXkwOMkC94k3WtqEBfcnjWqhRd82qTat4SWKRE+9kUnynz/shm3I4ea2+qISvTIeGTNU7kJg==}
- dependencies:
- jju: 1.4.0
- dev: true
+ '@oxc-resolver/binding-linux-riscv64-gnu@11.20.0':
+ optional: true
- /json-stringify-safe@5.0.1:
- resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==}
- dev: true
+ '@oxc-resolver/binding-linux-riscv64-musl@11.20.0':
+ optional: true
- /json5@2.2.3:
- resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
- engines: {node: '>=6'}
- hasBin: true
- dev: true
+ '@oxc-resolver/binding-linux-s390x-gnu@11.20.0':
+ optional: true
- /jsonc-parser@3.2.1:
- resolution: {integrity: sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==}
- dev: true
+ '@oxc-resolver/binding-linux-x64-gnu@11.20.0':
+ optional: true
- /jsonfile@4.0.0:
- resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==}
- optionalDependencies:
- graceful-fs: 4.2.11
- dev: true
+ '@oxc-resolver/binding-linux-x64-musl@11.20.0':
+ optional: true
- /jsonfile@6.1.0:
- resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
+ '@oxc-resolver/binding-openharmony-arm64@11.20.0':
+ optional: true
+
+ '@oxc-resolver/binding-wasm32-wasi@11.20.0':
dependencies:
- universalify: 2.0.1
- optionalDependencies:
- graceful-fs: 4.2.11
- dev: true
+ '@emnapi/core': 1.10.0
+ '@emnapi/runtime': 1.10.0
+ '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)
+ optional: true
- /jsonlines@0.1.1:
- resolution: {integrity: sha512-ekDrAGso79Cvf+dtm+mL8OBI2bmAOt3gssYs833De/C9NmIpWDWyUO4zPgB5x2/OhY366dkhgfPMYfwZF7yOZA==}
- dev: true
+ '@oxc-resolver/binding-win32-arm64-msvc@11.20.0':
+ optional: true
- /jsonparse@1.3.1:
- resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==}
- engines: {'0': node >= 0.2.0}
- dev: true
+ '@oxc-resolver/binding-win32-x64-msvc@11.20.0':
+ optional: true
- /keyv@4.5.4:
- resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
- dependencies:
- json-buffer: 3.0.1
- dev: true
+ '@rollup/rollup-android-arm-eabi@4.39.0':
+ optional: true
- /kind-of@6.0.3:
- resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
- engines: {node: '>=0.10.0'}
- dev: true
+ '@rollup/rollup-android-arm-eabi@4.61.0':
+ optional: true
- /kleur@4.1.5:
- resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==}
- engines: {node: '>=6'}
- dev: true
+ '@rollup/rollup-android-arm64@4.39.0':
+ optional: true
- /knip@2.43.0:
- resolution: {integrity: sha512-xXtBpC+XiHZzqBoXtvqH0sLV3iSMu9yPIUoP9GRZVUHAegQyDjC4jOTRfFgc5gJKrfqW4NKc71t7l85NqYieUg==}
- engines: {node: '>=16.17.0 <17 || >=18.6.0'}
- hasBin: true
- dependencies:
- '@ericcornelissen/bash-parser': 0.5.2
- '@npmcli/map-workspaces': 3.0.4
- '@pkgjs/parseargs': 0.11.0
- '@pnpm/logger': 5.0.0
- '@pnpm/workspace.pkgs-graph': 2.0.11(@pnpm/logger@5.0.0)
- '@snyk/github-codeowners': 1.1.0
- chalk: 5.3.0
- easy-table: 1.2.0
- fast-glob: 3.3.2
- globby: 13.2.2
- jiti: 1.21.0
- js-yaml: 4.1.0
- micromatch: 4.0.5
- minimist: 1.2.8
- pretty-ms: 8.0.0
- strip-json-comments: 5.0.1
- summary: 2.1.0
- typescript: 5.4.3
- zod: 3.22.4
- zod-validation-error: 1.5.0(zod@3.22.4)
- transitivePeerDependencies:
- - domexception
- dev: true
+ '@rollup/rollup-android-arm64@4.61.0':
+ optional: true
- /latest-version@7.0.0:
- resolution: {integrity: sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==}
- engines: {node: '>=14.16'}
- dependencies:
- package-json: 8.1.1
- dev: true
+ '@rollup/rollup-darwin-arm64@4.39.0':
+ optional: true
- /lilconfig@2.1.0:
- resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
- engines: {node: '>=10'}
- dev: true
+ '@rollup/rollup-darwin-arm64@4.61.0':
+ optional: true
- /lines-and-columns@1.2.4:
- resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
- dev: true
+ '@rollup/rollup-darwin-x64@4.39.0':
+ optional: true
- /load-json-file@6.2.0:
- resolution: {integrity: sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ==}
- engines: {node: '>=8'}
- dependencies:
- graceful-fs: 4.2.11
- parse-json: 5.2.0
- strip-bom: 4.0.0
- type-fest: 0.6.0
- dev: true
+ '@rollup/rollup-darwin-x64@4.61.0':
+ optional: true
- /load-tsconfig@0.2.5:
- resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==}
- engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
- dev: true
+ '@rollup/rollup-freebsd-arm64@4.39.0':
+ optional: true
- /load-yaml-file@0.2.0:
- resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==}
- engines: {node: '>=6'}
- dependencies:
- graceful-fs: 4.2.11
- js-yaml: 3.14.1
- pify: 4.0.1
- strip-bom: 3.0.0
- dev: true
+ '@rollup/rollup-freebsd-arm64@4.61.0':
+ optional: true
- /local-pkg@0.4.3:
- resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==}
- engines: {node: '>=14'}
- dev: true
+ '@rollup/rollup-freebsd-x64@4.39.0':
+ optional: true
- /locate-path@5.0.0:
- resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
- engines: {node: '>=8'}
- dependencies:
- p-locate: 4.1.0
- dev: true
+ '@rollup/rollup-freebsd-x64@4.61.0':
+ optional: true
- /locate-path@6.0.0:
- resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
- engines: {node: '>=10'}
- dependencies:
- p-locate: 5.0.0
- dev: true
+ '@rollup/rollup-linux-arm-gnueabihf@4.39.0':
+ optional: true
- /lodash.curry@4.1.1:
- resolution: {integrity: sha512-/u14pXGviLaweY5JI0IUzgzF2J6Ne8INyzAZjImcryjgkZ+ebruBxy2/JaOOkTqScddcYtakjhSaeemV8lR0tA==}
- dev: true
+ '@rollup/rollup-linux-arm-gnueabihf@4.61.0':
+ optional: true
- /lodash.sortby@4.7.0:
- resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==}
- dev: true
+ '@rollup/rollup-linux-arm-musleabihf@4.39.0':
+ optional: true
- /lodash.startcase@4.4.0:
- resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==}
- dev: true
+ '@rollup/rollup-linux-arm-musleabihf@4.61.0':
+ optional: true
- /lodash@4.17.21:
- resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
- dev: true
+ '@rollup/rollup-linux-arm64-gnu@4.39.0':
+ optional: true
- /loupe@2.3.7:
- resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==}
- dependencies:
- get-func-name: 2.0.2
- dev: true
+ '@rollup/rollup-linux-arm64-gnu@4.61.0':
+ optional: true
- /lowercase-keys@3.0.0:
- resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==}
- engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
- dev: true
+ '@rollup/rollup-linux-arm64-musl@4.39.0':
+ optional: true
- /lru-cache@10.2.0:
- resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==}
- engines: {node: 14 || >=16.14}
- dev: true
+ '@rollup/rollup-linux-arm64-musl@4.61.0':
+ optional: true
- /lru-cache@4.1.5:
- resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==}
- dependencies:
- pseudomap: 1.0.2
- yallist: 2.1.2
- dev: true
+ '@rollup/rollup-linux-loong64-gnu@4.61.0':
+ optional: true
- /lru-cache@6.0.0:
- resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
- engines: {node: '>=10'}
- dependencies:
- yallist: 4.0.0
- dev: true
+ '@rollup/rollup-linux-loong64-musl@4.61.0':
+ optional: true
- /lru-cache@7.18.3:
- resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==}
- engines: {node: '>=12'}
- dev: true
+ '@rollup/rollup-linux-loongarch64-gnu@4.39.0':
+ optional: true
- /magic-string@0.16.0:
- resolution: {integrity: sha512-c4BEos3y6G2qO0B9X7K0FVLOPT9uGrjYwYRLFmDqyl5YMboUviyecnXWp94fJTSMwPw2/sf+CEYt5AGpmklkkQ==}
- dependencies:
- vlq: 0.2.3
- dev: true
+ '@rollup/rollup-linux-powerpc64le-gnu@4.39.0':
+ optional: true
- /magic-string@0.30.8:
- resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==}
- engines: {node: '>=12'}
- dependencies:
- '@jridgewell/sourcemap-codec': 1.4.15
- dev: true
-
- /make-fetch-happen@10.2.1:
- resolution: {integrity: sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==}
- engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
- dependencies:
- agentkeepalive: 4.5.0
- cacache: 16.1.3
- http-cache-semantics: 4.1.1
- http-proxy-agent: 5.0.0
- https-proxy-agent: 5.0.1
- is-lambda: 1.0.1
- lru-cache: 7.18.3
- minipass: 3.3.6
- minipass-collect: 1.0.2
- minipass-fetch: 2.1.2
- minipass-flush: 1.0.5
- minipass-pipeline: 1.2.4
- negotiator: 0.6.3
- promise-retry: 2.0.1
- socks-proxy-agent: 7.0.0
- ssri: 9.0.1
- transitivePeerDependencies:
- - bluebird
- - supports-color
- dev: true
-
- /make-fetch-happen@11.1.1:
- resolution: {integrity: sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dependencies:
- agentkeepalive: 4.5.0
- cacache: 17.1.4
- http-cache-semantics: 4.1.1
- http-proxy-agent: 5.0.0
- https-proxy-agent: 5.0.1
- is-lambda: 1.0.1
- lru-cache: 7.18.3
- minipass: 5.0.0
- minipass-fetch: 3.0.4
- minipass-flush: 1.0.5
- minipass-pipeline: 1.2.4
- negotiator: 0.6.3
- promise-retry: 2.0.1
- socks-proxy-agent: 7.0.0
- ssri: 10.0.5
- transitivePeerDependencies:
- - supports-color
- dev: true
+ '@rollup/rollup-linux-ppc64-gnu@4.61.0':
+ optional: true
- /map-age-cleaner@0.1.3:
- resolution: {integrity: sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==}
- engines: {node: '>=6'}
- dependencies:
- p-defer: 1.0.0
- dev: true
+ '@rollup/rollup-linux-ppc64-musl@4.61.0':
+ optional: true
- /map-obj@1.0.1:
- resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==}
- engines: {node: '>=0.10.0'}
- dev: true
+ '@rollup/rollup-linux-riscv64-gnu@4.39.0':
+ optional: true
- /map-obj@2.0.0:
- resolution: {integrity: sha512-TzQSV2DiMYgoF5RycneKVUzIa9bQsj/B3tTgsE3dOGqlzHnGIDaC7XBE7grnA+8kZPnfqSGFe95VHc2oc0VFUQ==}
- engines: {node: '>=4'}
- dev: true
+ '@rollup/rollup-linux-riscv64-gnu@4.61.0':
+ optional: true
- /map-obj@4.3.0:
- resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==}
- engines: {node: '>=8'}
- dev: true
+ '@rollup/rollup-linux-riscv64-musl@4.39.0':
+ optional: true
- /mem@6.1.1:
- resolution: {integrity: sha512-Ci6bIfq/UgcxPTYa8dQQ5FY3BzKkT894bwXWXxC/zqs0XgMO2cT20CGkOqda7gZNkmK5VP4x89IGZ6K7hfbn3Q==}
- engines: {node: '>=8'}
- dependencies:
- map-age-cleaner: 0.1.3
- mimic-fn: 3.1.0
- dev: true
+ '@rollup/rollup-linux-riscv64-musl@4.61.0':
+ optional: true
- /mem@8.1.1:
- resolution: {integrity: sha512-qFCFUDs7U3b8mBDPyz5EToEKoAkgCzqquIgi9nkkR9bixxOVOre+09lbuH7+9Kn2NFpm56M3GUWVbU2hQgdACA==}
- engines: {node: '>=10'}
- dependencies:
- map-age-cleaner: 0.1.3
- mimic-fn: 3.1.0
- dev: true
+ '@rollup/rollup-linux-s390x-gnu@4.39.0':
+ optional: true
- /meow@6.1.1:
- resolution: {integrity: sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg==}
- engines: {node: '>=8'}
- dependencies:
- '@types/minimist': 1.2.5
- camelcase-keys: 6.2.2
- decamelize-keys: 1.1.1
- hard-rejection: 2.1.0
- minimist-options: 4.1.0
- normalize-package-data: 2.5.0
- read-pkg-up: 7.0.1
- redent: 3.0.0
- trim-newlines: 3.0.1
- type-fest: 0.13.1
- yargs-parser: 18.1.3
- dev: true
-
- /merge-stream@2.0.0:
- resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
- dev: true
-
- /merge2@1.4.1:
- resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
- engines: {node: '>= 8'}
- dev: true
+ '@rollup/rollup-linux-s390x-gnu@4.61.0':
+ optional: true
- /micromatch@4.0.5:
- resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
- engines: {node: '>=8.6'}
- dependencies:
- braces: 3.0.2
- picomatch: 2.3.1
- dev: true
+ '@rollup/rollup-linux-x64-gnu@4.39.0':
+ optional: true
- /mimic-fn@2.1.0:
- resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
- engines: {node: '>=6'}
- dev: true
+ '@rollup/rollup-linux-x64-gnu@4.61.0':
+ optional: true
- /mimic-fn@3.1.0:
- resolution: {integrity: sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==}
- engines: {node: '>=8'}
- dev: true
+ '@rollup/rollup-linux-x64-musl@4.39.0':
+ optional: true
- /mimic-response@3.1.0:
- resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==}
- engines: {node: '>=10'}
- dev: true
+ '@rollup/rollup-linux-x64-musl@4.61.0':
+ optional: true
- /mimic-response@4.0.0:
- resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==}
- engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
- dev: true
+ '@rollup/rollup-openbsd-x64@4.61.0':
+ optional: true
- /min-indent@1.0.1:
- resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
- engines: {node: '>=4'}
- dev: true
+ '@rollup/rollup-openharmony-arm64@4.61.0':
+ optional: true
- /minimatch@3.1.2:
- resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
- dependencies:
- brace-expansion: 1.1.11
- dev: true
+ '@rollup/rollup-win32-arm64-msvc@4.39.0':
+ optional: true
- /minimatch@5.1.6:
- resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==}
- engines: {node: '>=10'}
- dependencies:
- brace-expansion: 2.0.1
- dev: true
+ '@rollup/rollup-win32-arm64-msvc@4.61.0':
+ optional: true
- /minimatch@9.0.3:
- resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==}
- engines: {node: '>=16 || 14 >=14.17'}
- dependencies:
- brace-expansion: 2.0.1
- dev: true
+ '@rollup/rollup-win32-ia32-msvc@4.39.0':
+ optional: true
- /minimist-options@4.1.0:
- resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==}
- engines: {node: '>= 6'}
- dependencies:
- arrify: 1.0.1
- is-plain-obj: 1.1.0
- kind-of: 6.0.3
- dev: true
+ '@rollup/rollup-win32-ia32-msvc@4.61.0':
+ optional: true
- /minimist@1.2.8:
- resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
- dev: true
+ '@rollup/rollup-win32-x64-gnu@4.61.0':
+ optional: true
- /minipass-collect@1.0.2:
- resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==}
- engines: {node: '>= 8'}
- dependencies:
- minipass: 3.3.6
- dev: true
+ '@rollup/rollup-win32-x64-msvc@4.39.0':
+ optional: true
- /minipass-fetch@2.1.2:
- resolution: {integrity: sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==}
- engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
- dependencies:
- minipass: 3.3.6
- minipass-sized: 1.0.3
- minizlib: 2.1.2
- optionalDependencies:
- encoding: 0.1.13
- dev: true
+ '@rollup/rollup-win32-x64-msvc@4.61.0':
+ optional: true
- /minipass-fetch@3.0.4:
- resolution: {integrity: sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dependencies:
- minipass: 7.0.4
- minipass-sized: 1.0.3
- minizlib: 2.1.2
- optionalDependencies:
- encoding: 0.1.13
- dev: true
+ '@standard-schema/spec@1.1.0': {}
- /minipass-flush@1.0.5:
- resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==}
- engines: {node: '>= 8'}
+ '@stylistic/eslint-plugin-js@1.8.1(eslint@8.57.1)':
dependencies:
- minipass: 3.3.6
- dev: true
+ '@types/eslint': 8.56.12
+ acorn: 8.15.0
+ escape-string-regexp: 4.0.0
+ eslint: 8.57.1
+ eslint-visitor-keys: 3.4.3
+ espree: 9.6.1
- /minipass-json-stream@1.0.1:
- resolution: {integrity: sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==}
+ '@stylistic/eslint-plugin-ts@1.8.1(eslint@8.57.1)(typescript@5.7.3)':
dependencies:
- jsonparse: 1.3.1
- minipass: 3.3.6
- dev: true
+ '@stylistic/eslint-plugin-js': 1.8.1(eslint@8.57.1)
+ '@types/eslint': 8.56.12
+ '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.7.3)
+ eslint: 8.57.1
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
- /minipass-pipeline@1.2.4:
- resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==}
- engines: {node: '>=8'}
+ '@tybys/wasm-util@0.10.2':
dependencies:
- minipass: 3.3.6
- dev: true
+ tslib: 2.8.1
+ optional: true
- /minipass-sized@1.0.3:
- resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==}
- engines: {node: '>=8'}
+ '@types/chai@5.2.3':
dependencies:
- minipass: 3.3.6
- dev: true
+ '@types/deep-eql': 4.0.2
+ assertion-error: 2.0.1
- /minipass@3.3.6:
- resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==}
- engines: {node: '>=8'}
- dependencies:
- yallist: 4.0.0
- dev: true
+ '@types/deep-eql@4.0.2': {}
- /minipass@5.0.0:
- resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==}
- engines: {node: '>=8'}
- dev: true
+ '@types/eslint@8.56.12':
+ dependencies:
+ '@types/estree': 1.0.7
+ '@types/json-schema': 7.0.15
- /minipass@7.0.4:
- resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==}
- engines: {node: '>=16 || 14 >=14.17'}
- dev: true
+ '@types/estree@1.0.7': {}
- /minizlib@2.1.2:
- resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==}
- engines: {node: '>= 8'}
- dependencies:
- minipass: 3.3.6
- yallist: 4.0.0
- dev: true
+ '@types/estree@1.0.9': {}
- /mixme@0.5.10:
- resolution: {integrity: sha512-5H76ANWinB1H3twpJ6JY8uvAtpmFvHNArpilJAjXRKXSDDLPIMoZArw5SH0q9z+lLs8IrMw7Q2VWpWimFKFT1Q==}
- engines: {node: '>= 8.0.0'}
- dev: true
+ '@types/json-schema@7.0.15': {}
- /mkdirp@1.0.4:
- resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==}
- engines: {node: '>=10'}
- hasBin: true
- dev: true
+ '@types/node@12.20.55': {}
- /mlly@1.6.1:
- resolution: {integrity: sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==}
+ '@types/node@20.19.41':
dependencies:
- acorn: 8.11.3
- pathe: 1.1.2
- pkg-types: 1.0.3
- ufo: 1.5.3
- dev: true
+ undici-types: 6.21.0
- /ms@2.1.2:
- resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
- dev: true
+ '@types/semver@7.7.0': {}
- /ms@2.1.3:
- resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
- dev: true
-
- /mz@2.7.0:
- resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
+ '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3)':
dependencies:
- any-promise: 1.3.0
- object-assign: 4.1.1
- thenify-all: 1.6.0
- dev: true
-
- /nanoid@3.3.7:
- resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
- engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
- hasBin: true
- dev: true
+ '@eslint-community/regexpp': 4.12.1
+ '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.7.3)
+ '@typescript-eslint/scope-manager': 6.21.0
+ '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.1)(typescript@5.7.3)
+ '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.7.3)
+ '@typescript-eslint/visitor-keys': 6.21.0
+ debug: 4.4.0
+ eslint: 8.57.1
+ graphemer: 1.4.0
+ ignore: 5.3.1
+ natural-compare: 1.4.0
+ semver: 7.6.0
+ ts-api-utils: 1.4.3(typescript@5.7.3)
+ optionalDependencies:
+ typescript: 5.7.3
+ transitivePeerDependencies:
+ - supports-color
- /ndjson@2.0.0:
- resolution: {integrity: sha512-nGl7LRGrzugTtaFcJMhLbpzJM6XdivmbkdlaGcrk/LXg2KL/YBC6z1g70xh0/al+oFuVFP8N8kiWRucmeEH/qQ==}
- engines: {node: '>=10'}
- hasBin: true
+ '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3)':
dependencies:
- json-stringify-safe: 5.0.1
- minimist: 1.2.8
- readable-stream: 3.6.2
- split2: 3.2.2
- through2: 4.0.2
- dev: true
-
- /negotiator@0.6.3:
- resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==}
- engines: {node: '>= 0.6'}
- dev: true
-
- /node-fetch@3.0.0-beta.9:
- resolution: {integrity: sha512-RdbZCEynH2tH46+tj0ua9caUHVWrd/RHnRfvly2EVdqGmI3ndS1Vn/xjm5KuGejDt2RNDQsVRLPNd2QPwcewVg==}
- engines: {node: ^10.17 || >=12.3}
- dependencies:
- data-uri-to-buffer: 3.0.1
- fetch-blob: 2.1.2
+ '@eslint-community/regexpp': 4.12.1
+ '@typescript-eslint/parser': 7.18.0(eslint@8.57.1)(typescript@5.7.3)
+ '@typescript-eslint/scope-manager': 7.18.0
+ '@typescript-eslint/type-utils': 7.18.0(eslint@8.57.1)(typescript@5.7.3)
+ '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.7.3)
+ '@typescript-eslint/visitor-keys': 7.18.0
+ eslint: 8.57.1
+ graphemer: 1.4.0
+ ignore: 5.3.1
+ natural-compare: 1.4.0
+ ts-api-utils: 1.4.3(typescript@5.7.3)
+ optionalDependencies:
+ typescript: 5.7.3
transitivePeerDependencies:
- - domexception
- dev: true
+ - supports-color
- /node-gyp-build@4.8.0:
- resolution: {integrity: sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==}
- hasBin: true
- requiresBuild: true
- dev: false
+ '@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.7.3)':
+ dependencies:
+ '@typescript-eslint/scope-manager': 6.21.0
+ '@typescript-eslint/types': 6.21.0
+ '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.7.3)
+ '@typescript-eslint/visitor-keys': 6.21.0
+ debug: 4.4.0
+ eslint: 8.57.1
+ optionalDependencies:
+ typescript: 5.7.3
+ transitivePeerDependencies:
+ - supports-color
- /node-gyp@9.4.1:
- resolution: {integrity: sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ==}
- engines: {node: ^12.13 || ^14.13 || >=16}
- hasBin: true
+ '@typescript-eslint/parser@7.18.0(eslint@8.57.1)(typescript@5.7.3)':
dependencies:
- env-paths: 2.2.1
- exponential-backoff: 3.1.1
- glob: 7.2.3
- graceful-fs: 4.2.11
- make-fetch-happen: 10.2.1
- nopt: 6.0.0
- npmlog: 6.0.2
- rimraf: 3.0.2
- semver: 7.6.0
- tar: 6.2.1
- which: 2.0.2
+ '@typescript-eslint/scope-manager': 7.18.0
+ '@typescript-eslint/types': 7.18.0
+ '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.7.3)
+ '@typescript-eslint/visitor-keys': 7.18.0
+ debug: 4.4.0
+ eslint: 8.57.1
+ optionalDependencies:
+ typescript: 5.7.3
transitivePeerDependencies:
- - bluebird
- supports-color
- dev: true
- /nopt@6.0.0:
- resolution: {integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==}
- engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
- hasBin: true
+ '@typescript-eslint/scope-manager@6.21.0':
dependencies:
- abbrev: 1.1.1
- dev: true
+ '@typescript-eslint/types': 6.21.0
+ '@typescript-eslint/visitor-keys': 6.21.0
- /normalize-package-data@2.5.0:
- resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==}
+ '@typescript-eslint/scope-manager@7.18.0':
dependencies:
- hosted-git-info: 2.8.9
- resolve: 1.22.8
- semver: 5.7.2
- validate-npm-package-license: 3.0.4
- dev: true
+ '@typescript-eslint/types': 7.18.0
+ '@typescript-eslint/visitor-keys': 7.18.0
- /normalize-package-data@5.0.0:
- resolution: {integrity: sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+ '@typescript-eslint/type-utils@6.21.0(eslint@8.57.1)(typescript@5.7.3)':
dependencies:
- hosted-git-info: 6.1.1
- is-core-module: 2.13.1
- semver: 7.6.0
- validate-npm-package-license: 3.0.4
- dev: true
+ '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.7.3)
+ '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.7.3)
+ debug: 4.4.0
+ eslint: 8.57.1
+ ts-api-utils: 1.4.3(typescript@5.7.3)
+ optionalDependencies:
+ typescript: 5.7.3
+ transitivePeerDependencies:
+ - supports-color
- /normalize-path@3.0.0:
- resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
- engines: {node: '>=0.10.0'}
+ '@typescript-eslint/type-utils@7.18.0(eslint@8.57.1)(typescript@5.7.3)':
+ dependencies:
+ '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.7.3)
+ '@typescript-eslint/utils': 7.18.0(eslint@8.57.1)(typescript@5.7.3)
+ debug: 4.4.0
+ eslint: 8.57.1
+ ts-api-utils: 1.4.3(typescript@5.7.3)
+ optionalDependencies:
+ typescript: 5.7.3
+ transitivePeerDependencies:
+ - supports-color
- /normalize-url@8.0.1:
- resolution: {integrity: sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==}
- engines: {node: '>=14.16'}
- dev: true
+ '@typescript-eslint/types@6.21.0': {}
- /npm-bundled@3.0.0:
- resolution: {integrity: sha512-Vq0eyEQy+elFpzsKjMss9kxqb9tG3YHg4dsyWuUENuzvSUWe1TCnW/vV9FkhvBk/brEDoDiVd+M1Btosa6ImdQ==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dependencies:
- npm-normalize-package-bin: 3.0.1
- dev: true
+ '@typescript-eslint/types@7.18.0': {}
- /npm-check-updates@16.14.18:
- resolution: {integrity: sha512-9iaRe9ohx9ykdbLjPRIYcq1A0RkrPYUx9HmQK1JIXhfxtJCNE/+497H9Z4PGH6GWRALbz5KF+1iZoySK2uSEpQ==}
- engines: {node: '>=14.14'}
- hasBin: true
+ '@typescript-eslint/typescript-estree@6.21.0(typescript@5.7.3)':
dependencies:
- '@types/semver-utils': 1.1.3
- chalk: 5.3.0
- cli-table3: 0.6.4
- commander: 10.0.1
- fast-memoize: 2.5.2
- find-up: 5.0.0
- fp-and-or: 0.1.4
- get-stdin: 8.0.0
+ '@typescript-eslint/types': 6.21.0
+ '@typescript-eslint/visitor-keys': 6.21.0
+ debug: 4.4.0
globby: 11.1.0
- hosted-git-info: 5.2.1
- ini: 4.1.2
- js-yaml: 4.1.0
- json-parse-helpfulerror: 1.0.3
- jsonlines: 0.1.1
- lodash: 4.17.21
- make-fetch-happen: 11.1.1
+ is-glob: 4.0.3
minimatch: 9.0.3
- p-map: 4.0.0
- pacote: 15.2.0
- parse-github-url: 1.0.2
- progress: 2.0.3
- prompts-ncu: 3.0.0
- rc-config-loader: 4.1.3
- remote-git-tags: 3.0.0
- rimraf: 5.0.5
semver: 7.6.0
- semver-utils: 1.1.4
- source-map-support: 0.5.21
- spawn-please: 2.0.2
- strip-ansi: 7.1.0
- strip-json-comments: 5.0.1
- untildify: 4.0.0
- update-notifier: 6.0.2
+ ts-api-utils: 1.4.3(typescript@5.7.3)
+ optionalDependencies:
+ typescript: 5.7.3
transitivePeerDependencies:
- - bluebird
- supports-color
- dev: true
- /npm-install-checks@6.3.0:
- resolution: {integrity: sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+ '@typescript-eslint/typescript-estree@7.18.0(typescript@5.7.3)':
dependencies:
+ '@typescript-eslint/types': 7.18.0
+ '@typescript-eslint/visitor-keys': 7.18.0
+ debug: 4.4.0
+ globby: 11.1.0
+ is-glob: 4.0.3
+ minimatch: 9.0.9
semver: 7.6.0
- dev: true
-
- /npm-normalize-package-bin@3.0.1:
- resolution: {integrity: sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dev: true
+ ts-api-utils: 1.4.3(typescript@5.7.3)
+ optionalDependencies:
+ typescript: 5.7.3
+ transitivePeerDependencies:
+ - supports-color
- /npm-package-arg@10.1.0:
- resolution: {integrity: sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+ '@typescript-eslint/utils@6.21.0(eslint@8.57.1)(typescript@5.7.3)':
dependencies:
- hosted-git-info: 6.1.1
- proc-log: 3.0.0
+ '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.1)
+ '@types/json-schema': 7.0.15
+ '@types/semver': 7.7.0
+ '@typescript-eslint/scope-manager': 6.21.0
+ '@typescript-eslint/types': 6.21.0
+ '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.7.3)
+ eslint: 8.57.1
semver: 7.6.0
- validate-npm-package-name: 5.0.0
- dev: true
-
- /npm-packlist@7.0.4:
- resolution: {integrity: sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dependencies:
- ignore-walk: 6.0.4
- dev: true
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
- /npm-pick-manifest@8.0.2:
- resolution: {integrity: sha512-1dKY+86/AIiq1tkKVD3l0WI+Gd3vkknVGAggsFeBkTvbhMQ1OND/LKkYv4JtXPKUJ8bOTCyLiqEg2P6QNdK+Gg==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+ '@typescript-eslint/utils@7.18.0(eslint@8.57.1)(typescript@5.7.3)':
dependencies:
- npm-install-checks: 6.3.0
- npm-normalize-package-bin: 3.0.1
- npm-package-arg: 10.1.0
- semver: 7.6.0
- dev: true
-
- /npm-registry-fetch@14.0.5:
- resolution: {integrity: sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dependencies:
- make-fetch-happen: 11.1.1
- minipass: 5.0.0
- minipass-fetch: 3.0.4
- minipass-json-stream: 1.0.1
- minizlib: 2.1.2
- npm-package-arg: 10.1.0
- proc-log: 3.0.0
+ '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.1)
+ '@typescript-eslint/scope-manager': 7.18.0
+ '@typescript-eslint/types': 7.18.0
+ '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.7.3)
+ eslint: 8.57.1
transitivePeerDependencies:
- supports-color
- dev: true
+ - typescript
- /npm-run-path@4.0.1:
- resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
- engines: {node: '>=8'}
+ '@typescript-eslint/visitor-keys@6.21.0':
dependencies:
- path-key: 3.1.1
- dev: true
+ '@typescript-eslint/types': 6.21.0
+ eslint-visitor-keys: 3.4.3
- /npmlog@6.0.2:
- resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==}
- engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
+ '@typescript-eslint/visitor-keys@7.18.0':
dependencies:
- are-we-there-yet: 3.0.1
- console-control-strings: 1.1.0
- gauge: 4.0.4
- set-blocking: 2.0.0
- dev: true
-
- /object-assign@4.1.1:
- resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
- engines: {node: '>=0.10.0'}
- dev: true
+ '@typescript-eslint/types': 7.18.0
+ eslint-visitor-keys: 3.4.3
- /object-inspect@1.13.1:
- resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==}
- dev: true
+ '@ungap/structured-clone@1.3.0': {}
- /object-keys@1.1.1:
- resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
- engines: {node: '>= 0.4'}
- dev: true
-
- /object-pairs@0.1.0:
- resolution: {integrity: sha512-3ECr6K831I4xX/Mduxr9UC+HPOz/d6WKKYj9p4cmC8Lg8p7g8gitzsxNX5IWlSIgFWN/a4JgrJaoAMKn20oKwA==}
- dev: true
-
- /object-values@1.0.0:
- resolution: {integrity: sha512-+8hwcz/JnQ9EpLIXzN0Rs7DLsBpJNT/xYehtB/jU93tHYr5BFEO8E+JGQNOSqE7opVzz5cGksKFHt7uUJVLSjQ==}
- engines: {node: '>=0.10.0'}
- dev: true
+ '@vitest/expect@4.1.8':
+ dependencies:
+ '@standard-schema/spec': 1.1.0
+ '@types/chai': 5.2.3
+ '@vitest/spy': 4.1.8
+ '@vitest/utils': 4.1.8
+ chai: 6.2.2
+ tinyrainbow: 3.1.0
- /object.assign@4.1.5:
- resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==}
- engines: {node: '>= 0.4'}
+ '@vitest/mocker@4.1.8(vite@7.3.2(@types/node@20.19.41)(jiti@2.7.0)(yaml@2.9.0))':
dependencies:
- call-bind: 1.0.7
- define-properties: 1.2.1
- has-symbols: 1.0.3
- object-keys: 1.1.1
- dev: true
+ '@vitest/spy': 4.1.8
+ estree-walker: 3.0.3
+ magic-string: 0.30.21
+ optionalDependencies:
+ vite: 7.3.2(@types/node@20.19.41)(jiti@2.7.0)(yaml@2.9.0)
- /once@1.4.0:
- resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
+ '@vitest/pretty-format@4.1.8':
dependencies:
- wrappy: 1.0.2
- dev: true
+ tinyrainbow: 3.1.0
- /onetime@5.1.2:
- resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
- engines: {node: '>=6'}
+ '@vitest/runner@4.1.8':
dependencies:
- mimic-fn: 2.1.0
- dev: true
+ '@vitest/utils': 4.1.8
+ pathe: 2.0.3
- /openapi-typescript-fetch@1.1.3:
- resolution: {integrity: sha512-smLZPck4OkKMNExcw8jMgrMOGgVGx2N/s6DbKL2ftNl77g5HfoGpZGFy79RBzU/EkaO0OZpwBnslfdBfh7ZcWg==}
- engines: {node: '>= 12.0.0', npm: '>= 7.0.0'}
- dev: false
+ '@vitest/snapshot@4.1.8':
+ dependencies:
+ '@vitest/pretty-format': 4.1.8
+ '@vitest/utils': 4.1.8
+ magic-string: 0.30.21
+ pathe: 2.0.3
- /os-tmpdir@1.0.2:
- resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==}
- engines: {node: '>=0.10.0'}
- dev: true
+ '@vitest/spy@4.1.8': {}
- /outdent@0.5.0:
- resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==}
- dev: true
+ '@vitest/utils@4.1.8':
+ dependencies:
+ '@vitest/pretty-format': 4.1.8
+ convert-source-map: 2.0.0
+ tinyrainbow: 3.1.0
- /p-cancelable@3.0.0:
- resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==}
- engines: {node: '>=12.20'}
- dev: true
+ acorn-jsx@5.3.2(acorn@8.15.0):
+ dependencies:
+ acorn: 8.15.0
- /p-defer@1.0.0:
- resolution: {integrity: sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==}
- engines: {node: '>=4'}
- dev: true
+ acorn@8.15.0: {}
- /p-filter@2.1.0:
- resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==}
- engines: {node: '>=8'}
+ ajv@6.12.6:
dependencies:
- p-map: 2.1.0
- dev: true
+ fast-deep-equal: 3.1.3
+ fast-json-stable-stringify: 2.1.0
+ json-schema-traverse: 0.4.1
+ uri-js: 4.4.1
- /p-limit@2.3.0:
- resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
- engines: {node: '>=6'}
- dependencies:
- p-try: 2.2.0
- dev: true
+ ansi-regex@5.0.1: {}
- /p-limit@3.1.0:
- resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
- engines: {node: '>=10'}
+ ansi-styles@4.3.0:
dependencies:
- yocto-queue: 0.1.0
- dev: true
+ color-convert: 2.0.1
- /p-limit@4.0.0:
- resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==}
- engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
- dependencies:
- yocto-queue: 1.0.0
- dev: true
+ any-promise@1.3.0: {}
- /p-locate@4.1.0:
- resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
- engines: {node: '>=8'}
+ argparse@1.0.10:
dependencies:
- p-limit: 2.3.0
- dev: true
+ sprintf-js: 1.0.3
- /p-locate@5.0.0:
- resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
- engines: {node: '>=10'}
- dependencies:
- p-limit: 3.1.0
- dev: true
+ argparse@2.0.1: {}
- /p-map@2.1.0:
- resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==}
- engines: {node: '>=6'}
- dev: true
+ array-union@2.1.0: {}
- /p-map@4.0.0:
- resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==}
- engines: {node: '>=10'}
- dependencies:
- aggregate-error: 3.1.0
- dev: true
+ assertion-error@2.0.1: {}
- /p-memoize@4.0.1:
- resolution: {integrity: sha512-km0sP12uE0dOZ5qP+s7kGVf07QngxyG0gS8sYFvFWhqlgzOsSy+m71aUejf/0akxj5W7gE//2G74qTv6b4iMog==}
- engines: {node: '>=10'}
- dependencies:
- mem: 6.1.1
- mimic-fn: 3.1.0
- dev: true
+ balanced-match@1.0.2: {}
- /p-try@2.2.0:
- resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
- engines: {node: '>=6'}
- dev: true
+ balanced-match@4.0.4: {}
- /package-json@8.1.1:
- resolution: {integrity: sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==}
- engines: {node: '>=14.16'}
+ better-path-resolve@1.0.0:
dependencies:
- got: 12.6.1
- registry-auth-token: 5.0.2
- registry-url: 6.0.1
- semver: 7.6.0
- dev: true
+ is-windows: 1.0.2
- /pacote@15.2.0:
- resolution: {integrity: sha512-rJVZeIwHTUta23sIZgEIM62WYwbmGbThdbnkt81ravBplQv+HjyroqnLRNH2+sLJHcGZmLRmhPwACqhfTcOmnA==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- hasBin: true
+ brace-expansion@1.1.14:
dependencies:
- '@npmcli/git': 4.1.0
- '@npmcli/installed-package-contents': 2.0.2
- '@npmcli/promise-spawn': 6.0.2
- '@npmcli/run-script': 6.0.2
- cacache: 17.1.4
- fs-minipass: 3.0.3
- minipass: 5.0.0
- npm-package-arg: 10.1.0
- npm-packlist: 7.0.4
- npm-pick-manifest: 8.0.2
- npm-registry-fetch: 14.0.5
- proc-log: 3.0.0
- promise-retry: 2.0.1
- read-package-json: 6.0.4
- read-package-json-fast: 3.0.2
- sigstore: 1.9.0
- ssri: 10.0.5
- tar: 6.2.1
- transitivePeerDependencies:
- - bluebird
- - supports-color
- dev: true
+ balanced-match: 1.0.2
+ concat-map: 0.0.1
- /parse-github-url@1.0.2:
- resolution: {integrity: sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==}
- engines: {node: '>=0.10.0'}
- hasBin: true
- dev: true
+ brace-expansion@2.1.1:
+ dependencies:
+ balanced-match: 1.0.2
- /parse-json@5.2.0:
- resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
- engines: {node: '>=8'}
+ brace-expansion@5.0.6:
dependencies:
- '@babel/code-frame': 7.24.2
- error-ex: 1.3.2
- json-parse-even-better-errors: 2.3.1
- lines-and-columns: 1.2.4
- dev: true
+ balanced-match: 4.0.4
- /parse-ms@3.0.0:
- resolution: {integrity: sha512-Tpb8Z7r7XbbtBTrM9UhpkzzaMrqA2VXMT3YChzYltwV3P3pM6t8wl7TvpMnSTosz1aQAdVib7kdoys7vYOPerw==}
- engines: {node: '>=12'}
- dev: true
+ braces@3.0.3:
+ dependencies:
+ fill-range: 7.1.1
- /parse-npm-tarball-url@3.0.0:
- resolution: {integrity: sha512-InpdgIdNe5xWMEUcrVQUniQKwnggBtJ7+SCwh7zQAZwbbIYZV9XdgJyhtmDSSvykFyQXoe4BINnzKTfCwWLs5g==}
- engines: {node: '>=8.15'}
+ bundle-require@5.1.0(esbuild@0.27.2):
dependencies:
- semver: 6.3.1
- dev: true
+ esbuild: 0.27.2
+ load-tsconfig: 0.2.5
- /path-browserify@1.0.1:
- resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
- dev: false
+ cac@6.7.14: {}
- /path-exists@4.0.0:
- resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
- engines: {node: '>=8'}
- dev: true
+ callsites@3.1.0: {}
- /path-is-absolute@1.0.1:
- resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
- engines: {node: '>=0.10.0'}
- dev: true
+ chai@6.2.2: {}
- /path-key@3.1.1:
- resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
- engines: {node: '>=8'}
- dev: true
+ chalk@4.1.2:
+ dependencies:
+ ansi-styles: 4.3.0
+ supports-color: 7.2.0
- /path-parse@1.0.7:
- resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
- dev: true
+ chalk@5.6.2: {}
- /path-scurry@1.10.1:
- resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==}
- engines: {node: '>=16 || 14 >=14.17'}
+ changeset@0.2.6:
dependencies:
- lru-cache: 10.2.0
- minipass: 7.0.4
- dev: true
+ udc: 1.0.1
+ underscore: 1.13.6
- /path-temp@2.1.0:
- resolution: {integrity: sha512-cMMJTAZlion/RWRRC48UbrDymEIt+/YSD/l8NqjneyDw2rDOBQcP5yRkMB4CYGn47KMhZvbblBP7Z79OsMw72w==}
- engines: {node: '>=8.15'}
+ chokidar@4.0.3:
dependencies:
- unique-string: 2.0.0
- dev: true
+ readdirp: 4.1.1
- /path-type@4.0.0:
- resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
- engines: {node: '>=8'}
- dev: true
+ chownr@3.0.0: {}
- /pathe@1.1.2:
- resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==}
- dev: true
+ color-convert@2.0.1:
+ dependencies:
+ color-name: 1.1.4
- /pathval@1.1.1:
- resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==}
- dev: true
+ color-name@1.1.4: {}
- /picocolors@1.0.0:
- resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
- dev: true
+ commander@4.1.1: {}
- /picomatch@2.3.1:
- resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
- engines: {node: '>=8.6'}
- dev: true
+ compare-versions@6.1.1: {}
- /pify@4.0.1:
- resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==}
- engines: {node: '>=6'}
- dev: true
+ concat-map@0.0.1: {}
- /pirates@4.0.6:
- resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
- engines: {node: '>= 6'}
- dev: true
+ confbox@0.1.8: {}
- /pkg-dir@4.2.0:
- resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==}
- engines: {node: '>=8'}
+ consola@3.4.0: {}
+
+ convert-source-map@2.0.0: {}
+
+ cross-spawn@7.0.6:
dependencies:
- find-up: 4.1.0
- dev: true
+ path-key: 3.1.1
+ shebang-command: 2.0.0
+ which: 2.0.2
- /pkg-types@1.0.3:
- resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==}
+ debug@4.4.0:
dependencies:
- jsonc-parser: 3.2.1
- mlly: 1.6.1
- pathe: 1.1.2
- dev: true
+ ms: 2.1.3
- /platform@1.3.6:
- resolution: {integrity: sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==}
- dev: false
+ debug@4.4.3:
+ dependencies:
+ ms: 2.1.3
- /possible-typed-array-names@1.0.0:
- resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==}
- engines: {node: '>= 0.4'}
- dev: true
+ deep-is@0.1.4: {}
- /postcss-load-config@3.1.4:
- resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==}
- engines: {node: '>= 10'}
- peerDependencies:
- postcss: '>=8.0.9'
- ts-node: '>=9.0.0'
- peerDependenciesMeta:
- postcss:
- optional: true
- ts-node:
- optional: true
+ dir-glob@3.0.1:
dependencies:
- lilconfig: 2.1.0
- yaml: 1.10.2
- dev: true
+ path-type: 4.0.0
- /postcss@8.4.38:
- resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==}
- engines: {node: ^10 || ^12 || >=14}
+ dockerfile-ast@0.7.1:
dependencies:
- nanoid: 3.3.7
- picocolors: 1.0.0
- source-map-js: 1.2.0
- dev: true
+ vscode-languageserver-textdocument: 1.0.12
+ vscode-languageserver-types: 3.18.0
- /preferred-pm@3.1.3:
- resolution: {integrity: sha512-MkXsENfftWSRpzCzImcp4FRsCc3y1opwB73CfCNWyzMqArju2CrlMHlqB7VexKiPEOjGMbttv1r9fSCn5S610w==}
- engines: {node: '>=10'}
+ doctrine@3.0.0:
dependencies:
- find-up: 5.0.0
- find-yarn-workspace-root2: 1.2.16
- path-exists: 4.0.0
- which-pm: 2.0.0
- dev: true
+ esutils: 2.0.3
- /prettier@2.8.8:
- resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==}
- engines: {node: '>=10.13.0'}
- hasBin: true
- dev: true
+ dotenv@16.6.1: {}
- /pretty-format@29.7.0:
- resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==}
- engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ e2b@2.28.0:
dependencies:
- '@jest/schemas': 29.6.3
- ansi-styles: 5.2.0
- react-is: 18.2.0
- dev: true
+ '@bufbuild/protobuf': 2.12.0
+ '@connectrpc/connect': 2.0.0-rc.3(@bufbuild/protobuf@2.12.0)
+ '@connectrpc/connect-web': 2.0.0-rc.3(@bufbuild/protobuf@2.12.0)(@connectrpc/connect@2.0.0-rc.3(@bufbuild/protobuf@2.12.0))
+ chalk: 5.6.2
+ compare-versions: 6.1.1
+ dockerfile-ast: 0.7.1
+ glob: 11.1.0
+ openapi-fetch: 0.14.1
+ platform: 1.3.6
+ tar: 7.5.16
+ undici: 7.27.0
- /pretty-ms@8.0.0:
- resolution: {integrity: sha512-ASJqOugUF1bbzI35STMBUpZqdfYKlJugy6JBziGi2EE+AL5JPJGSzvpeVXojxrr0ViUYoToUjb5kjSEGf7Y83Q==}
- engines: {node: '>=14.16'}
- dependencies:
- parse-ms: 3.0.0
- dev: true
+ es-module-lexer@2.1.0: {}
- /proc-log@3.0.0:
- resolution: {integrity: sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dev: true
+ esbuild@0.27.2:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.27.2
+ '@esbuild/android-arm': 0.27.2
+ '@esbuild/android-arm64': 0.27.2
+ '@esbuild/android-x64': 0.27.2
+ '@esbuild/darwin-arm64': 0.27.2
+ '@esbuild/darwin-x64': 0.27.2
+ '@esbuild/freebsd-arm64': 0.27.2
+ '@esbuild/freebsd-x64': 0.27.2
+ '@esbuild/linux-arm': 0.27.2
+ '@esbuild/linux-arm64': 0.27.2
+ '@esbuild/linux-ia32': 0.27.2
+ '@esbuild/linux-loong64': 0.27.2
+ '@esbuild/linux-mips64el': 0.27.2
+ '@esbuild/linux-ppc64': 0.27.2
+ '@esbuild/linux-riscv64': 0.27.2
+ '@esbuild/linux-s390x': 0.27.2
+ '@esbuild/linux-x64': 0.27.2
+ '@esbuild/netbsd-arm64': 0.27.2
+ '@esbuild/netbsd-x64': 0.27.2
+ '@esbuild/openbsd-arm64': 0.27.2
+ '@esbuild/openbsd-x64': 0.27.2
+ '@esbuild/openharmony-arm64': 0.27.2
+ '@esbuild/sunos-x64': 0.27.2
+ '@esbuild/win32-arm64': 0.27.2
+ '@esbuild/win32-ia32': 0.27.2
+ '@esbuild/win32-x64': 0.27.2
+
+ esbuild@0.27.7:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.27.7
+ '@esbuild/android-arm': 0.27.7
+ '@esbuild/android-arm64': 0.27.7
+ '@esbuild/android-x64': 0.27.7
+ '@esbuild/darwin-arm64': 0.27.7
+ '@esbuild/darwin-x64': 0.27.7
+ '@esbuild/freebsd-arm64': 0.27.7
+ '@esbuild/freebsd-x64': 0.27.7
+ '@esbuild/linux-arm': 0.27.7
+ '@esbuild/linux-arm64': 0.27.7
+ '@esbuild/linux-ia32': 0.27.7
+ '@esbuild/linux-loong64': 0.27.7
+ '@esbuild/linux-mips64el': 0.27.7
+ '@esbuild/linux-ppc64': 0.27.7
+ '@esbuild/linux-riscv64': 0.27.7
+ '@esbuild/linux-s390x': 0.27.7
+ '@esbuild/linux-x64': 0.27.7
+ '@esbuild/netbsd-arm64': 0.27.7
+ '@esbuild/netbsd-x64': 0.27.7
+ '@esbuild/openbsd-arm64': 0.27.7
+ '@esbuild/openbsd-x64': 0.27.7
+ '@esbuild/openharmony-arm64': 0.27.7
+ '@esbuild/sunos-x64': 0.27.7
+ '@esbuild/win32-arm64': 0.27.7
+ '@esbuild/win32-ia32': 0.27.7
+ '@esbuild/win32-x64': 0.27.7
+
+ escape-string-regexp@4.0.0: {}
+
+ eslint-plugin-unused-imports@3.2.0(@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1):
+ dependencies:
+ eslint: 8.57.1
+ eslint-rule-composer: 0.3.0
+ optionalDependencies:
+ '@typescript-eslint/eslint-plugin': 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3)
- /progress@2.0.3:
- resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==}
- engines: {node: '>=0.4.0'}
- dev: true
+ eslint-rule-composer@0.3.0: {}
- /promise-inflight@1.0.1:
- resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==}
- peerDependencies:
- bluebird: '*'
- peerDependenciesMeta:
- bluebird:
- optional: true
- dev: true
+ eslint-scope@7.2.2:
+ dependencies:
+ esrecurse: 4.3.0
+ estraverse: 5.3.0
- /promise-retry@2.0.1:
- resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==}
- engines: {node: '>=10'}
+ eslint-visitor-keys@3.4.3: {}
+
+ eslint@8.57.1:
dependencies:
- err-code: 2.0.3
- retry: 0.12.0
- dev: true
+ '@eslint-community/eslint-utils': 4.7.0(eslint@8.57.1)
+ '@eslint-community/regexpp': 4.12.1
+ '@eslint/eslintrc': 2.1.4
+ '@eslint/js': 8.57.1
+ '@humanwhocodes/config-array': 0.13.0
+ '@humanwhocodes/module-importer': 1.0.1
+ '@nodelib/fs.walk': 1.2.8
+ '@ungap/structured-clone': 1.3.0
+ ajv: 6.12.6
+ chalk: 4.1.2
+ cross-spawn: 7.0.6
+ debug: 4.4.0
+ doctrine: 3.0.0
+ escape-string-regexp: 4.0.0
+ eslint-scope: 7.2.2
+ eslint-visitor-keys: 3.4.3
+ espree: 9.6.1
+ esquery: 1.6.0
+ esutils: 2.0.3
+ fast-deep-equal: 3.1.3
+ file-entry-cache: 6.0.1
+ find-up: 5.0.0
+ glob-parent: 6.0.2
+ globals: 13.24.0
+ graphemer: 1.4.0
+ ignore: 5.3.1
+ imurmurhash: 0.1.4
+ is-glob: 4.0.3
+ is-path-inside: 3.0.3
+ js-yaml: 4.1.1
+ json-stable-stringify-without-jsonify: 1.0.1
+ levn: 0.4.1
+ lodash.merge: 4.6.2
+ minimatch: 3.1.2
+ natural-compare: 1.4.0
+ optionator: 0.9.4
+ strip-ansi: 6.0.1
+ text-table: 0.2.0
+ transitivePeerDependencies:
+ - supports-color
- /prompts-ncu@3.0.0:
- resolution: {integrity: sha512-qyz9UxZ5MlPKWVhWrCmSZ1ahm2GVYdjLb8og2sg0IPth1KRuhcggHGuijz0e41dkx35p1t1q3GRISGH7QGALFA==}
- engines: {node: '>= 14'}
+ espree@9.6.1:
dependencies:
- kleur: 4.1.5
- sisteransi: 1.0.5
- dev: true
+ acorn: 8.15.0
+ acorn-jsx: 5.3.2(acorn@8.15.0)
+ eslint-visitor-keys: 3.4.3
- /proto-list@1.2.4:
- resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==}
- dev: true
+ esprima@4.0.1: {}
- /pseudomap@1.0.2:
- resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==}
- dev: true
+ esquery@1.6.0:
+ dependencies:
+ estraverse: 5.3.0
- /punycode@2.3.1:
- resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
- engines: {node: '>=6'}
- dev: true
+ esrecurse@4.3.0:
+ dependencies:
+ estraverse: 5.3.0
- /pupa@3.1.0:
- resolution: {integrity: sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==}
- engines: {node: '>=12.20'}
+ estraverse@5.3.0: {}
+
+ estree-walker@3.0.3:
dependencies:
- escape-goat: 4.0.0
- dev: true
+ '@types/estree': 1.0.9
- /queue-microtask@1.2.3:
- resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
- dev: true
+ esutils@2.0.3: {}
- /quick-lru@4.0.1:
- resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==}
- engines: {node: '>=8'}
- dev: true
+ expect-type@1.3.0: {}
- /quick-lru@5.1.1:
- resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==}
- engines: {node: '>=10'}
- dev: true
+ extendable-error@0.1.7: {}
- /rc-config-loader@4.1.3:
- resolution: {integrity: sha512-kD7FqML7l800i6pS6pvLyIE2ncbk9Du8Q0gp/4hMPhJU6ZxApkoLcGD8ZeqgiAlfwZ6BlETq6qqe+12DUL207w==}
- dependencies:
- debug: 4.3.4
- js-yaml: 4.1.0
- json5: 2.2.3
- require-from-string: 2.0.2
- transitivePeerDependencies:
- - supports-color
- dev: true
+ fast-deep-equal@3.1.3: {}
- /rc@1.2.8:
- resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
- hasBin: true
+ fast-glob@3.3.3:
dependencies:
- deep-extend: 0.6.0
- ini: 1.3.8
- minimist: 1.2.8
- strip-json-comments: 2.0.1
- dev: true
+ '@nodelib/fs.stat': 2.0.5
+ '@nodelib/fs.walk': 1.2.8
+ glob-parent: 5.1.2
+ merge2: 1.4.1
+ micromatch: 4.0.8
+
+ fast-json-stable-stringify@2.1.0: {}
- /react-is@18.2.0:
- resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==}
- dev: true
+ fast-levenshtein@2.0.6: {}
- /read-package-json-fast@3.0.2:
- resolution: {integrity: sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+ fastq@1.19.0:
dependencies:
- json-parse-even-better-errors: 3.0.1
- npm-normalize-package-bin: 3.0.1
- dev: true
+ reusify: 1.0.4
- /read-package-json@6.0.4:
- resolution: {integrity: sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+ fd-package-json@2.0.0:
dependencies:
- glob: 10.3.10
- json-parse-even-better-errors: 3.0.1
- normalize-package-data: 5.0.0
- npm-normalize-package-bin: 3.0.1
- dev: true
+ walk-up-path: 4.0.0
- /read-pkg-up@7.0.1:
- resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==}
- engines: {node: '>=8'}
+ fdir@6.5.0(picomatch@4.0.4):
+ optionalDependencies:
+ picomatch: 4.0.4
+
+ file-entry-cache@6.0.1:
dependencies:
- find-up: 4.1.0
- read-pkg: 5.2.0
- type-fest: 0.8.1
- dev: true
+ flat-cache: 3.2.0
- /read-pkg@5.2.0:
- resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==}
- engines: {node: '>=8'}
+ fill-range@7.1.1:
dependencies:
- '@types/normalize-package-data': 2.4.4
- normalize-package-data: 2.5.0
- parse-json: 5.2.0
- type-fest: 0.6.0
- dev: true
+ to-regex-range: 5.0.1
- /read-yaml-file@1.1.0:
- resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==}
- engines: {node: '>=6'}
+ find-up@4.1.0:
dependencies:
- graceful-fs: 4.2.11
- js-yaml: 3.14.1
- pify: 4.0.1
- strip-bom: 3.0.0
- dev: true
+ locate-path: 5.0.0
+ path-exists: 4.0.0
- /readable-stream@3.6.2:
- resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
- engines: {node: '>= 6'}
+ find-up@5.0.0:
dependencies:
- inherits: 2.0.4
- string_decoder: 1.3.0
- util-deprecate: 1.0.2
- dev: true
+ locate-path: 6.0.0
+ path-exists: 4.0.0
- /readdirp@3.6.0:
- resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
- engines: {node: '>=8.10.0'}
+ fix-dts-default-cjs-exports@1.0.1:
dependencies:
- picomatch: 2.3.1
- dev: true
+ magic-string: 0.30.21
+ mlly: 1.8.0
+ rollup: 4.39.0
- /redent@3.0.0:
- resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==}
- engines: {node: '>=8'}
+ flat-cache@3.2.0:
dependencies:
- indent-string: 4.0.0
- strip-indent: 3.0.0
- dev: true
+ flatted: 3.3.3
+ keyv: 4.5.4
+ rimraf: 3.0.2
- /regenerator-runtime@0.14.1:
- resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
- dev: true
+ flatted@3.3.3: {}
- /regexp.prototype.flags@1.5.2:
- resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==}
- engines: {node: '>= 0.4'}
+ foreground-child@3.3.1:
dependencies:
- call-bind: 1.0.7
- define-properties: 1.2.1
- es-errors: 1.3.0
- set-function-name: 2.0.2
- dev: true
+ cross-spawn: 7.0.6
+ signal-exit: 4.1.0
- /registry-auth-token@5.0.2:
- resolution: {integrity: sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==}
- engines: {node: '>=14'}
+ formatly@0.3.0:
dependencies:
- '@pnpm/npm-conf': 2.2.2
- dev: true
+ fd-package-json: 2.0.0
- /registry-url@6.0.1:
- resolution: {integrity: sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==}
- engines: {node: '>=12'}
+ fs-extra@7.0.1:
dependencies:
- rc: 1.2.8
- dev: true
-
- /remote-git-tags@3.0.0:
- resolution: {integrity: sha512-C9hAO4eoEsX+OXA4rla66pXZQ+TLQ8T9dttgQj18yuKlPMTVkIkdYXvlMC55IuUsIkV6DpmQYi10JKFLaU+l7w==}
- engines: {node: '>=8'}
- dev: true
+ graceful-fs: 4.2.11
+ jsonfile: 4.0.0
+ universalify: 0.1.2
- /rename-overwrite@4.0.4:
- resolution: {integrity: sha512-5MC+p5npnyaJlFkwTHb0pqU2mkUkkW65ZWH8qwxcDlv+5nchtalcdzG+gaaianbWWwvwxi7vu7WSg6jdCweKug==}
- engines: {node: '>=12.10'}
+ fs-extra@8.1.0:
dependencies:
- '@zkochan/rimraf': 2.1.3
- fs-extra: 10.1.0
- dev: true
+ graceful-fs: 4.2.11
+ jsonfile: 4.0.0
+ universalify: 0.1.2
- /require-directory@2.1.1:
- resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
- engines: {node: '>=0.10.0'}
- dev: true
+ fs.realpath@1.0.0: {}
- /require-from-string@2.0.2:
- resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
- engines: {node: '>=0.10.0'}
- dev: true
+ fsevents@2.3.3:
+ optional: true
- /require-main-filename@2.0.0:
- resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}
- dev: true
+ glob-parent@5.1.2:
+ dependencies:
+ is-glob: 4.0.3
- /resolve-alpn@1.2.1:
- resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==}
- dev: true
+ glob-parent@6.0.2:
+ dependencies:
+ is-glob: 4.0.3
- /resolve-from@5.0.0:
- resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
- engines: {node: '>=8'}
- dev: true
+ glob@11.1.0:
+ dependencies:
+ foreground-child: 3.3.1
+ jackspeak: 4.2.3
+ minimatch: 10.2.5
+ minipass: 7.1.3
+ package-json-from-dist: 1.0.1
+ path-scurry: 2.0.2
- /resolve@1.22.8:
- resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
- hasBin: true
+ glob@7.2.3:
dependencies:
- is-core-module: 2.13.1
- path-parse: 1.0.7
- supports-preserve-symlinks-flag: 1.0.0
- dev: true
+ fs.realpath: 1.0.0
+ inflight: 1.0.6
+ inherits: 2.0.4
+ minimatch: 3.1.2
+ once: 1.4.0
+ path-is-absolute: 1.0.1
- /responselike@3.0.0:
- resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==}
- engines: {node: '>=14.16'}
+ globals@13.24.0:
dependencies:
- lowercase-keys: 3.0.0
- dev: true
+ type-fest: 0.20.2
- /retry@0.12.0:
- resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==}
- engines: {node: '>= 4'}
- dev: true
+ globby@11.1.0:
+ dependencies:
+ array-union: 2.1.0
+ dir-glob: 3.0.1
+ fast-glob: 3.3.3
+ ignore: 5.3.1
+ merge2: 1.4.1
+ slash: 3.0.0
- /reusify@1.0.4:
- resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
- engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
- dev: true
+ graceful-fs@4.2.11: {}
- /reverse-arguments@1.0.0:
- resolution: {integrity: sha512-/x8uIPdTafBqakK0TmPNJzgkLP+3H+yxpUJhCQHsLBg1rYEVNR2D8BRYNWQhVBjyOd7oo1dZRVzIkwMY2oqfYQ==}
- dev: true
+ graphemer@1.4.0: {}
- /rimraf@3.0.2:
- resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
- hasBin: true
- dependencies:
- glob: 7.2.3
- dev: true
+ has-flag@4.0.0: {}
- /rimraf@5.0.5:
- resolution: {integrity: sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==}
- engines: {node: '>=14'}
- hasBin: true
+ ignore@5.3.1: {}
+
+ import-fresh@3.3.1:
dependencies:
- glob: 10.3.10
- dev: true
+ parent-module: 1.0.1
+ resolve-from: 4.0.0
- /rollup@3.29.4:
- resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==}
- engines: {node: '>=14.18.0', npm: '>=8.0.0'}
- hasBin: true
- optionalDependencies:
- fsevents: 2.3.3
- dev: true
+ imurmurhash@0.1.4: {}
- /rollup@4.13.0:
- resolution: {integrity: sha512-3YegKemjoQnYKmsBlOHfMLVPPA5xLkQ8MHLLSw/fBrFaVkEayL51DilPpNNLq1exr98F2B1TzrV0FUlN3gWRPg==}
- engines: {node: '>=18.0.0', npm: '>=8.0.0'}
- hasBin: true
+ inflight@1.0.6:
dependencies:
- '@types/estree': 1.0.5
- optionalDependencies:
- '@rollup/rollup-android-arm-eabi': 4.13.0
- '@rollup/rollup-android-arm64': 4.13.0
- '@rollup/rollup-darwin-arm64': 4.13.0
- '@rollup/rollup-darwin-x64': 4.13.0
- '@rollup/rollup-linux-arm-gnueabihf': 4.13.0
- '@rollup/rollup-linux-arm64-gnu': 4.13.0
- '@rollup/rollup-linux-arm64-musl': 4.13.0
- '@rollup/rollup-linux-riscv64-gnu': 4.13.0
- '@rollup/rollup-linux-x64-gnu': 4.13.0
- '@rollup/rollup-linux-x64-musl': 4.13.0
- '@rollup/rollup-win32-arm64-msvc': 4.13.0
- '@rollup/rollup-win32-ia32-msvc': 4.13.0
- '@rollup/rollup-win32-x64-msvc': 4.13.0
- fsevents: 2.3.3
- dev: true
+ once: 1.4.0
+ wrappy: 1.0.2
- /run-parallel@1.2.0:
- resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
- dependencies:
- queue-microtask: 1.2.3
- dev: true
-
- /safe-array-concat@1.1.2:
- resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==}
- engines: {node: '>=0.4'}
- dependencies:
- call-bind: 1.0.7
- get-intrinsic: 1.2.4
- has-symbols: 1.0.3
- isarray: 2.0.5
- dev: true
-
- /safe-buffer@5.2.1:
- resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
- dev: true
-
- /safe-regex-test@1.0.3:
- resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.7
- es-errors: 1.3.0
- is-regex: 1.1.4
- dev: true
-
- /safer-buffer@2.1.2:
- resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
- requiresBuild: true
- dev: true
-
- /semver-diff@4.0.0:
- resolution: {integrity: sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==}
- engines: {node: '>=12'}
- dependencies:
- semver: 7.6.0
- dev: true
+ inherits@2.0.4: {}
- /semver-utils@1.1.4:
- resolution: {integrity: sha512-EjnoLE5OGmDAVV/8YDoN5KiajNadjzIp9BAHOhYeQHt7j0UWxjmgsx4YD48wp4Ue1Qogq38F1GNUJNqF1kKKxA==}
- dev: true
+ is-extglob@2.1.1: {}
- /semver@5.7.2:
- resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==}
- hasBin: true
- dev: true
+ is-glob@4.0.3:
+ dependencies:
+ is-extglob: 2.1.1
- /semver@6.3.1:
- resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
- hasBin: true
- dev: true
+ is-number@7.0.0: {}
- /semver@7.6.0:
- resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==}
- engines: {node: '>=10'}
- hasBin: true
- dependencies:
- lru-cache: 6.0.0
- dev: true
-
- /set-blocking@2.0.0:
- resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
- dev: true
-
- /set-function-length@1.2.2:
- resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
- engines: {node: '>= 0.4'}
- dependencies:
- define-data-property: 1.1.4
- es-errors: 1.3.0
- function-bind: 1.1.2
- get-intrinsic: 1.2.4
- gopd: 1.0.1
- has-property-descriptors: 1.0.2
- dev: true
-
- /set-function-name@2.0.2:
- resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==}
- engines: {node: '>= 0.4'}
- dependencies:
- define-data-property: 1.1.4
- es-errors: 1.3.0
- functions-have-names: 1.2.3
- has-property-descriptors: 1.0.2
- dev: true
-
- /shebang-command@1.2.0:
- resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==}
- engines: {node: '>=0.10.0'}
- dependencies:
- shebang-regex: 1.0.0
- dev: true
+ is-path-inside@3.0.3: {}
- /shebang-command@2.0.0:
- resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
- engines: {node: '>=8'}
+ is-subdir@1.2.0:
dependencies:
- shebang-regex: 3.0.0
- dev: true
-
- /shebang-regex@1.0.0:
- resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==}
- engines: {node: '>=0.10.0'}
- dev: true
+ better-path-resolve: 1.0.0
- /shebang-regex@3.0.0:
- resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
- engines: {node: '>=8'}
- dev: true
+ is-windows@1.0.2: {}
- /shell-quote-word@1.0.1:
- resolution: {integrity: sha512-lT297f1WLAdq0A4O+AknIFRP6kkiI3s8C913eJ0XqBxJbZPGWUNkRQk2u8zk4bEAjUJ5i+fSLwB6z1HzeT+DEg==}
- dev: true
+ isexe@2.0.0: {}
- /side-channel@1.0.6:
- resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==}
- engines: {node: '>= 0.4'}
+ jackspeak@4.2.3:
dependencies:
- call-bind: 1.0.7
- es-errors: 1.3.0
- get-intrinsic: 1.2.4
- object-inspect: 1.13.1
- dev: true
+ '@isaacs/cliui': 9.0.0
- /siginfo@2.0.0:
- resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
- dev: true
+ jiti@2.7.0: {}
- /signal-exit@3.0.7:
- resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
- dev: true
+ joycon@3.1.1: {}
- /signal-exit@4.1.0:
- resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
- engines: {node: '>=14'}
- dev: true
+ js-yaml@3.14.2:
+ dependencies:
+ argparse: 1.0.10
+ esprima: 4.0.1
- /sigstore@1.9.0:
- resolution: {integrity: sha512-0Zjz0oe37d08VeOtBIuB6cRriqXse2e8w+7yIy2XSXjshRKxbc2KkhXjL229jXSxEm7UbcjS76wcJDGQddVI9A==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- hasBin: true
+ js-yaml@4.1.1:
dependencies:
- '@sigstore/bundle': 1.1.0
- '@sigstore/protobuf-specs': 0.2.1
- '@sigstore/sign': 1.0.0
- '@sigstore/tuf': 1.0.3
- make-fetch-happen: 11.1.1
- transitivePeerDependencies:
- - supports-color
- dev: true
+ argparse: 2.0.1
- /sisteransi@1.0.5:
- resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
- dev: true
+ json-buffer@3.0.1: {}
- /slash@3.0.0:
- resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
- engines: {node: '>=8'}
- dev: true
+ json-schema-traverse@0.4.1: {}
- /slash@4.0.0:
- resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==}
- engines: {node: '>=12'}
- dev: true
+ json-stable-stringify-without-jsonify@1.0.1: {}
- /smart-buffer@4.2.0:
- resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==}
- engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
- dev: true
+ jsonfile@4.0.0:
+ optionalDependencies:
+ graceful-fs: 4.2.11
- /smartwrap@2.0.2:
- resolution: {integrity: sha512-vCsKNQxb7PnCNd2wY1WClWifAc2lwqsG8OaswpJkVJsvMGcnEntdTCDajZCkk93Ay1U3t/9puJmb525Rg5MZBA==}
- engines: {node: '>=6'}
- hasBin: true
+ keyv@4.5.4:
dependencies:
- array.prototype.flat: 1.3.2
- breakword: 1.0.6
- grapheme-splitter: 1.0.4
- strip-ansi: 6.0.1
- wcwidth: 1.0.1
- yargs: 15.4.1
- dev: true
+ json-buffer: 3.0.1
- /socks-proxy-agent@7.0.0:
- resolution: {integrity: sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==}
- engines: {node: '>= 10'}
+ knip@5.88.1(@types/node@20.19.41)(typescript@5.7.3):
dependencies:
- agent-base: 6.0.2
- debug: 4.3.4
- socks: 2.8.1
- transitivePeerDependencies:
- - supports-color
- dev: true
+ '@nodelib/fs.walk': 1.2.8
+ '@types/node': 20.19.41
+ fast-glob: 3.3.3
+ formatly: 0.3.0
+ jiti: 2.7.0
+ minimist: 1.2.8
+ oxc-resolver: 11.20.0
+ picocolors: 1.1.1
+ picomatch: 4.0.4
+ smol-toml: 1.6.1
+ strip-json-comments: 5.0.3
+ typescript: 5.7.3
+ unbash: 2.2.0
+ yaml: 2.9.0
+ zod: 4.4.3
- /socks@2.8.1:
- resolution: {integrity: sha512-B6w7tkwNid7ToxjZ08rQMT8M9BJAf8DKx8Ft4NivzH0zBUfd6jldGcisJn/RLgxcX3FPNDdNQCUEMMT79b+oCQ==}
- engines: {node: '>= 10.0.0', npm: '>= 3.0.0'}
+ levn@0.4.1:
dependencies:
- ip-address: 9.0.5
- smart-buffer: 4.2.0
- dev: true
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
- /source-map-js@1.2.0:
- resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==}
- engines: {node: '>=0.10.0'}
- dev: true
+ lilconfig@3.1.2: {}
- /source-map-support@0.5.21:
- resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
- dependencies:
- buffer-from: 1.1.2
- source-map: 0.6.1
- dev: true
+ lines-and-columns@1.2.4: {}
- /source-map@0.6.1:
- resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
- engines: {node: '>=0.10.0'}
- dev: true
+ load-tsconfig@0.2.5: {}
- /source-map@0.8.0-beta.0:
- resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==}
- engines: {node: '>= 8'}
+ locate-path@5.0.0:
dependencies:
- whatwg-url: 7.1.0
- dev: true
+ p-locate: 4.1.0
- /spawn-please@2.0.2:
- resolution: {integrity: sha512-KM8coezO6ISQ89c1BzyWNtcn2V2kAVtwIXd3cN/V5a0xPYc1F/vydrRc01wsKFEQ/p+V1a4sw4z2yMITIXrgGw==}
- engines: {node: '>=14'}
+ locate-path@6.0.0:
dependencies:
- cross-spawn: 7.0.3
- dev: true
+ p-locate: 5.0.0
- /spawndamnit@2.0.0:
- resolution: {integrity: sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA==}
+ lodash.merge@4.6.2: {}
+
+ lru-cache@11.5.1: {}
+
+ lru-cache@6.0.0:
dependencies:
- cross-spawn: 5.1.0
- signal-exit: 3.0.7
- dev: true
+ yallist: 4.0.0
- /spdx-correct@3.2.0:
- resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==}
+ magic-string@0.30.21:
dependencies:
- spdx-expression-parse: 3.0.1
- spdx-license-ids: 3.0.17
- dev: true
+ '@jridgewell/sourcemap-codec': 1.5.5
- /spdx-exceptions@2.5.0:
- resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==}
- dev: true
+ merge2@1.4.1: {}
- /spdx-expression-parse@3.0.1:
- resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==}
+ micromatch@4.0.8:
dependencies:
- spdx-exceptions: 2.5.0
- spdx-license-ids: 3.0.17
- dev: true
-
- /spdx-license-ids@3.0.17:
- resolution: {integrity: sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==}
- dev: true
+ braces: 3.0.3
+ picomatch: 2.3.2
- /split2@3.2.2:
- resolution: {integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==}
+ minimatch@10.2.5:
dependencies:
- readable-stream: 3.6.2
- dev: true
+ brace-expansion: 5.0.6
- /sprintf-js@1.0.3:
- resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
- dev: true
+ minimatch@3.1.2:
+ dependencies:
+ brace-expansion: 1.1.14
- /sprintf-js@1.1.3:
- resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==}
- dev: true
+ minimatch@9.0.3:
+ dependencies:
+ brace-expansion: 2.1.1
- /ssri@10.0.5:
- resolution: {integrity: sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+ minimatch@9.0.9:
dependencies:
- minipass: 7.0.4
- dev: true
+ brace-expansion: 2.1.1
+
+ minimist@1.2.8: {}
- /ssri@9.0.1:
- resolution: {integrity: sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==}
- engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
+ minipass@7.1.3: {}
+
+ minizlib@3.1.0:
dependencies:
- minipass: 3.3.6
- dev: true
+ minipass: 7.1.3
- /stackback@0.0.2:
- resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
- dev: true
+ mlly@1.8.0:
+ dependencies:
+ acorn: 8.15.0
+ pathe: 2.0.3
+ pkg-types: 1.3.1
+ ufo: 1.6.1
- /std-env@3.7.0:
- resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==}
- dev: true
+ ms@2.1.3: {}
- /stream-transform@2.1.3:
- resolution: {integrity: sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ==}
+ mz@2.7.0:
dependencies:
- mixme: 0.5.10
- dev: true
+ any-promise: 1.3.0
+ object-assign: 4.1.1
+ thenify-all: 1.6.0
- /string-width@4.2.3:
- resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
- engines: {node: '>=8'}
+ nanoid@3.3.12: {}
+
+ natural-compare@1.4.0: {}
+
+ npm-check-updates@17.1.18: {}
+
+ object-assign@4.1.1: {}
+
+ obug@2.1.1: {}
+
+ once@1.4.0:
dependencies:
- emoji-regex: 8.0.0
- is-fullwidth-code-point: 3.0.0
- strip-ansi: 6.0.1
- dev: true
+ wrappy: 1.0.2
- /string-width@5.1.2:
- resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
- engines: {node: '>=12'}
+ openapi-fetch@0.14.1:
dependencies:
- eastasianwidth: 0.2.0
- emoji-regex: 9.2.2
- strip-ansi: 7.1.0
- dev: true
+ openapi-typescript-helpers: 0.0.15
- /string.fromcodepoint@0.2.1:
- resolution: {integrity: sha512-n69H31OnxSGSZyZbgBlvYIXlrMhJQ0dQAX1js1QDhpaUH6zmU3QYlj07bCwCNlPOu3oRXIubGPl2gDGnHsiCqg==}
- dev: true
+ openapi-typescript-helpers@0.0.15: {}
- /string.prototype.trim@1.2.9:
- resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==}
- engines: {node: '>= 0.4'}
+ optionator@0.9.4:
dependencies:
- call-bind: 1.0.7
- define-properties: 1.2.1
- es-abstract: 1.23.3
- es-object-atoms: 1.0.0
- dev: true
+ deep-is: 0.1.4
+ fast-levenshtein: 2.0.6
+ levn: 0.4.1
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
+ word-wrap: 1.2.5
- /string.prototype.trimend@1.0.8:
- resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==}
+ oxc-resolver@11.20.0:
+ optionalDependencies:
+ '@oxc-resolver/binding-android-arm-eabi': 11.20.0
+ '@oxc-resolver/binding-android-arm64': 11.20.0
+ '@oxc-resolver/binding-darwin-arm64': 11.20.0
+ '@oxc-resolver/binding-darwin-x64': 11.20.0
+ '@oxc-resolver/binding-freebsd-x64': 11.20.0
+ '@oxc-resolver/binding-linux-arm-gnueabihf': 11.20.0
+ '@oxc-resolver/binding-linux-arm-musleabihf': 11.20.0
+ '@oxc-resolver/binding-linux-arm64-gnu': 11.20.0
+ '@oxc-resolver/binding-linux-arm64-musl': 11.20.0
+ '@oxc-resolver/binding-linux-ppc64-gnu': 11.20.0
+ '@oxc-resolver/binding-linux-riscv64-gnu': 11.20.0
+ '@oxc-resolver/binding-linux-riscv64-musl': 11.20.0
+ '@oxc-resolver/binding-linux-s390x-gnu': 11.20.0
+ '@oxc-resolver/binding-linux-x64-gnu': 11.20.0
+ '@oxc-resolver/binding-linux-x64-musl': 11.20.0
+ '@oxc-resolver/binding-openharmony-arm64': 11.20.0
+ '@oxc-resolver/binding-wasm32-wasi': 11.20.0
+ '@oxc-resolver/binding-win32-arm64-msvc': 11.20.0
+ '@oxc-resolver/binding-win32-x64-msvc': 11.20.0
+
+ p-filter@2.1.0:
dependencies:
- call-bind: 1.0.7
- define-properties: 1.2.1
- es-object-atoms: 1.0.0
- dev: true
+ p-map: 2.1.0
- /string.prototype.trimstart@1.0.8:
- resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==}
- engines: {node: '>= 0.4'}
+ p-limit@2.3.0:
dependencies:
- call-bind: 1.0.7
- define-properties: 1.2.1
- es-object-atoms: 1.0.0
- dev: true
+ p-try: 2.2.0
- /string_decoder@1.3.0:
- resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
+ p-limit@3.1.0:
dependencies:
- safe-buffer: 5.2.1
- dev: true
+ yocto-queue: 0.1.0
- /strip-ansi@6.0.1:
- resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
- engines: {node: '>=8'}
+ p-locate@4.1.0:
dependencies:
- ansi-regex: 5.0.1
- dev: true
+ p-limit: 2.3.0
- /strip-ansi@7.1.0:
- resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
- engines: {node: '>=12'}
+ p-locate@5.0.0:
dependencies:
- ansi-regex: 6.0.1
- dev: true
+ p-limit: 3.1.0
- /strip-bom@3.0.0:
- resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
- engines: {node: '>=4'}
- dev: true
+ p-map@2.1.0: {}
- /strip-bom@4.0.0:
- resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==}
- engines: {node: '>=8'}
- dev: true
+ p-try@2.2.0: {}
- /strip-final-newline@2.0.0:
- resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
- engines: {node: '>=6'}
- dev: true
+ package-json-from-dist@1.0.1: {}
- /strip-indent@3.0.0:
- resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==}
- engines: {node: '>=8'}
+ parent-module@1.0.1:
dependencies:
- min-indent: 1.0.1
- dev: true
+ callsites: 3.1.0
- /strip-json-comments@2.0.1:
- resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==}
- engines: {node: '>=0.10.0'}
- dev: true
+ path-exists@4.0.0: {}
- /strip-json-comments@5.0.1:
- resolution: {integrity: sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==}
- engines: {node: '>=14.16'}
- dev: true
+ path-is-absolute@1.0.1: {}
- /strip-literal@1.3.0:
- resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==}
- dependencies:
- acorn: 8.11.3
- dev: true
+ path-key@3.1.1: {}
- /sucrase@3.35.0:
- resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==}
- engines: {node: '>=16 || 14 >=14.17'}
- hasBin: true
+ path-scurry@2.0.2:
dependencies:
- '@jridgewell/gen-mapping': 0.3.5
- commander: 4.1.1
- glob: 10.3.10
- lines-and-columns: 1.2.4
- mz: 2.7.0
- pirates: 4.0.6
- ts-interface-checker: 0.1.13
- dev: true
+ lru-cache: 11.5.1
+ minipass: 7.1.3
- /summary@2.1.0:
- resolution: {integrity: sha512-nMIjMrd5Z2nuB2RZCKJfFMjgS3fygbeyGk9PxPPaJR1RIcyN9yn4A63Isovzm3ZtQuEkLBVgMdPup8UeLH7aQw==}
- dev: true
+ path-type@4.0.0: {}
- /supports-color@5.5.0:
- resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
- engines: {node: '>=4'}
- dependencies:
- has-flag: 3.0.0
- dev: true
+ pathe@2.0.3: {}
- /supports-color@7.2.0:
- resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
- engines: {node: '>=8'}
- dependencies:
- has-flag: 4.0.0
- dev: true
+ picocolors@1.1.1: {}
- /supports-preserve-symlinks-flag@1.0.0:
- resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
- engines: {node: '>= 0.4'}
- dev: true
+ picomatch@2.3.2: {}
- /tar@6.2.1:
- resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==}
- engines: {node: '>=10'}
- dependencies:
- chownr: 2.0.0
- fs-minipass: 2.1.0
- minipass: 5.0.0
- minizlib: 2.1.2
- mkdirp: 1.0.4
- yallist: 4.0.0
- dev: true
+ picomatch@4.0.4: {}
- /term-size@2.2.1:
- resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==}
- engines: {node: '>=8'}
- dev: true
+ pify@4.0.1: {}
- /thenify-all@1.6.0:
- resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
- engines: {node: '>=0.8'}
+ pirates@4.0.6: {}
+
+ pkg-types@1.3.1:
dependencies:
- thenify: 3.3.1
- dev: true
+ confbox: 0.1.8
+ mlly: 1.8.0
+ pathe: 2.0.3
- /thenify@3.3.1:
- resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
+ platform@1.3.6: {}
+
+ postcss-load-config@6.0.1(jiti@2.7.0)(postcss@8.5.15)(yaml@2.9.0):
dependencies:
- any-promise: 1.3.0
- dev: true
+ lilconfig: 3.1.2
+ optionalDependencies:
+ jiti: 2.7.0
+ postcss: 8.5.15
+ yaml: 2.9.0
- /through2@4.0.2:
- resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==}
+ postcss@8.5.15:
dependencies:
- readable-stream: 3.6.2
- dev: true
+ nanoid: 3.3.12
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
- /tinybench@2.6.0:
- resolution: {integrity: sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==}
- dev: true
+ prelude-ls@1.2.1: {}
- /tinypool@0.7.0:
- resolution: {integrity: sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==}
- engines: {node: '>=14.0.0'}
- dev: true
+ prettier@3.6.2: {}
- /tinyspy@2.2.1:
- resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==}
- engines: {node: '>=14.0.0'}
- dev: true
+ punycode@2.3.1: {}
+
+ queue-microtask@1.2.3: {}
- /tmp@0.0.33:
- resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==}
- engines: {node: '>=0.6.0'}
+ read-yaml-file@1.1.0:
dependencies:
- os-tmpdir: 1.0.2
- dev: true
+ graceful-fs: 4.2.11
+ js-yaml: 3.14.2
+ pify: 4.0.1
+ strip-bom: 3.0.0
- /to-no-case@1.0.2:
- resolution: {integrity: sha512-Z3g735FxuZY8rodxV4gH7LxClE4H0hTIyHNIHdk+vpQxjLm0cwnKXq/OFVZ76SOQmto7txVcwSCwkU5kqp+FKg==}
- dev: true
+ readdirp@4.1.1: {}
- /to-pascal-case@1.0.0:
- resolution: {integrity: sha512-QGMWHqM6xPrcQW57S23c5/3BbYb0Tbe9p+ur98ckRnGDwD4wbbtDiYI38CfmMKNB5Iv0REjs5SNDntTwvDxzZA==}
- dependencies:
- to-space-case: 1.0.0
- dev: true
+ resolve-from@4.0.0: {}
- /to-regex-range@5.0.1:
- resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
- engines: {node: '>=8.0'}
- dependencies:
- is-number: 7.0.0
- dev: true
+ resolve-from@5.0.0: {}
- /to-space-case@1.0.0:
- resolution: {integrity: sha512-rLdvwXZ39VOn1IxGL3V6ZstoTbwLRckQmn/U8ZDLuWwIXNpuZDhQ3AiRUlhTbOXFVE9C+dR51wM0CBDhk31VcA==}
- dependencies:
- to-no-case: 1.0.2
- dev: true
+ reusify@1.0.4: {}
- /tr46@1.0.1:
- resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==}
+ rimraf@3.0.2:
dependencies:
- punycode: 2.3.1
- dev: true
-
- /tree-kill@1.2.2:
- resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
- hasBin: true
- dev: true
+ glob: 7.2.3
- /trim-newlines@3.0.1:
- resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==}
- engines: {node: '>=8'}
- dev: true
+ rollup@4.39.0:
+ dependencies:
+ '@types/estree': 1.0.7
+ optionalDependencies:
+ '@rollup/rollup-android-arm-eabi': 4.39.0
+ '@rollup/rollup-android-arm64': 4.39.0
+ '@rollup/rollup-darwin-arm64': 4.39.0
+ '@rollup/rollup-darwin-x64': 4.39.0
+ '@rollup/rollup-freebsd-arm64': 4.39.0
+ '@rollup/rollup-freebsd-x64': 4.39.0
+ '@rollup/rollup-linux-arm-gnueabihf': 4.39.0
+ '@rollup/rollup-linux-arm-musleabihf': 4.39.0
+ '@rollup/rollup-linux-arm64-gnu': 4.39.0
+ '@rollup/rollup-linux-arm64-musl': 4.39.0
+ '@rollup/rollup-linux-loongarch64-gnu': 4.39.0
+ '@rollup/rollup-linux-powerpc64le-gnu': 4.39.0
+ '@rollup/rollup-linux-riscv64-gnu': 4.39.0
+ '@rollup/rollup-linux-riscv64-musl': 4.39.0
+ '@rollup/rollup-linux-s390x-gnu': 4.39.0
+ '@rollup/rollup-linux-x64-gnu': 4.39.0
+ '@rollup/rollup-linux-x64-musl': 4.39.0
+ '@rollup/rollup-win32-arm64-msvc': 4.39.0
+ '@rollup/rollup-win32-ia32-msvc': 4.39.0
+ '@rollup/rollup-win32-x64-msvc': 4.39.0
+ fsevents: 2.3.3
- /ts-interface-checker@0.1.13:
- resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
- dev: true
+ rollup@4.61.0:
+ dependencies:
+ '@types/estree': 1.0.9
+ optionalDependencies:
+ '@rollup/rollup-android-arm-eabi': 4.61.0
+ '@rollup/rollup-android-arm64': 4.61.0
+ '@rollup/rollup-darwin-arm64': 4.61.0
+ '@rollup/rollup-darwin-x64': 4.61.0
+ '@rollup/rollup-freebsd-arm64': 4.61.0
+ '@rollup/rollup-freebsd-x64': 4.61.0
+ '@rollup/rollup-linux-arm-gnueabihf': 4.61.0
+ '@rollup/rollup-linux-arm-musleabihf': 4.61.0
+ '@rollup/rollup-linux-arm64-gnu': 4.61.0
+ '@rollup/rollup-linux-arm64-musl': 4.61.0
+ '@rollup/rollup-linux-loong64-gnu': 4.61.0
+ '@rollup/rollup-linux-loong64-musl': 4.61.0
+ '@rollup/rollup-linux-ppc64-gnu': 4.61.0
+ '@rollup/rollup-linux-ppc64-musl': 4.61.0
+ '@rollup/rollup-linux-riscv64-gnu': 4.61.0
+ '@rollup/rollup-linux-riscv64-musl': 4.61.0
+ '@rollup/rollup-linux-s390x-gnu': 4.61.0
+ '@rollup/rollup-linux-x64-gnu': 4.61.0
+ '@rollup/rollup-linux-x64-musl': 4.61.0
+ '@rollup/rollup-openbsd-x64': 4.61.0
+ '@rollup/rollup-openharmony-arm64': 4.61.0
+ '@rollup/rollup-win32-arm64-msvc': 4.61.0
+ '@rollup/rollup-win32-ia32-msvc': 4.61.0
+ '@rollup/rollup-win32-x64-gnu': 4.61.0
+ '@rollup/rollup-win32-x64-msvc': 4.61.0
+ fsevents: 2.3.3
- /tsup@6.7.0(typescript@5.4.3):
- resolution: {integrity: sha512-L3o8hGkaHnu5TdJns+mCqFsDBo83bJ44rlK7e6VdanIvpea4ArPcU3swWGsLVbXak1PqQx/V+SSmFPujBK+zEQ==}
- engines: {node: '>=14.18'}
- hasBin: true
- peerDependencies:
- '@swc/core': ^1
- postcss: ^8.4.12
- typescript: '>=4.1.0'
- peerDependenciesMeta:
- '@swc/core':
- optional: true
- postcss:
- optional: true
- typescript:
- optional: true
+ run-parallel@1.2.0:
dependencies:
- bundle-require: 4.0.2(esbuild@0.17.19)
- cac: 6.7.14
- chokidar: 3.6.0
- debug: 4.3.4
- esbuild: 0.17.19
- execa: 5.1.1
- globby: 11.1.0
- joycon: 3.1.1
- postcss-load-config: 3.1.4
- resolve-from: 5.0.0
- rollup: 3.29.4
- source-map: 0.8.0-beta.0
- sucrase: 3.35.0
- tree-kill: 1.2.2
- typescript: 5.4.3
- transitivePeerDependencies:
- - supports-color
- - ts-node
- dev: true
+ queue-microtask: 1.2.3
- /tty-table@4.2.3:
- resolution: {integrity: sha512-Fs15mu0vGzCrj8fmJNP7Ynxt5J7praPXqFN0leZeZBXJwkMxv9cb2D454k1ltrtUSJbZ4yH4e0CynsHLxmUfFA==}
- engines: {node: '>=8.0.0'}
- hasBin: true
+ semver@7.6.0:
dependencies:
- chalk: 4.1.2
- csv: 5.5.3
- kleur: 4.1.5
- smartwrap: 2.0.2
- strip-ansi: 6.0.1
- wcwidth: 1.0.1
- yargs: 17.7.2
- dev: true
+ lru-cache: 6.0.0
- /tuf-js@1.1.7:
- resolution: {integrity: sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+ shebang-command@2.0.0:
dependencies:
- '@tufjs/models': 1.0.4
- debug: 4.3.4
- make-fetch-happen: 11.1.1
- transitivePeerDependencies:
- - supports-color
- dev: true
+ shebang-regex: 3.0.0
- /type-detect@4.0.8:
- resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==}
- engines: {node: '>=4'}
- dev: true
+ shebang-regex@3.0.0: {}
- /type-fest@0.13.1:
- resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==}
- engines: {node: '>=10'}
- dev: true
+ siginfo@2.0.0: {}
- /type-fest@0.6.0:
- resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==}
- engines: {node: '>=8'}
- dev: true
+ signal-exit@4.1.0: {}
- /type-fest@0.8.1:
- resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==}
- engines: {node: '>=8'}
- dev: true
+ slash@3.0.0: {}
- /type-fest@1.4.0:
- resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==}
- engines: {node: '>=10'}
- dev: true
-
- /type-fest@2.19.0:
- resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==}
- engines: {node: '>=12.20'}
- dev: true
-
- /typed-array-buffer@1.0.2:
- resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.7
- es-errors: 1.3.0
- is-typed-array: 1.1.13
- dev: true
-
- /typed-array-byte-length@1.0.1:
- resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.7
- for-each: 0.3.3
- gopd: 1.0.1
- has-proto: 1.0.3
- is-typed-array: 1.1.13
- dev: true
-
- /typed-array-byte-offset@1.0.2:
- resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==}
- engines: {node: '>= 0.4'}
- dependencies:
- available-typed-arrays: 1.0.7
- call-bind: 1.0.7
- for-each: 0.3.3
- gopd: 1.0.1
- has-proto: 1.0.3
- is-typed-array: 1.1.13
- dev: true
-
- /typed-array-length@1.0.6:
- resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==}
- engines: {node: '>= 0.4'}
- dependencies:
- call-bind: 1.0.7
- for-each: 0.3.3
- gopd: 1.0.1
- has-proto: 1.0.3
- is-typed-array: 1.1.13
- possible-typed-array-names: 1.0.0
- dev: true
-
- /typedarray-to-buffer@3.1.5:
- resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==}
- dependencies:
- is-typedarray: 1.0.0
- dev: true
-
- /typescript@5.4.3:
- resolution: {integrity: sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==}
- engines: {node: '>=14.17'}
- hasBin: true
- dev: true
+ smol-toml@1.6.1: {}
- /udc@1.0.1:
- resolution: {integrity: sha512-jv+D9de1flsum5QkFtBdjyppCQAdz9kTck/0xST5Vx48T9LL2BYnw0Iw77dSKDQ9KZ/PS3qPO1vfXHDpLZlxcQ==}
- dev: true
+ source-map-js@1.2.1: {}
- /ufo@1.5.3:
- resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==}
- dev: true
+ source-map@0.7.6: {}
- /unbox-primitive@1.0.2:
- resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==}
+ spawndamnit@3.0.1:
dependencies:
- call-bind: 1.0.7
- has-bigints: 1.0.2
- has-symbols: 1.0.3
- which-boxed-primitive: 1.0.2
- dev: true
+ cross-spawn: 7.0.6
+ signal-exit: 4.1.0
- /underscore@1.13.6:
- resolution: {integrity: sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==}
- dev: true
+ sprintf-js@1.0.3: {}
- /undici-types@5.26.5:
- resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
- dev: true
+ stackback@0.0.2: {}
- /unescape-js@1.1.4:
- resolution: {integrity: sha512-42SD8NOQEhdYntEiUQdYq/1V/YHwr1HLwlHuTJB5InVVdOSbgI6xu8jK5q65yIzuFCfczzyDF/7hbGzVbyCw0g==}
- dependencies:
- string.fromcodepoint: 0.2.1
- dev: true
+ std-env@4.1.0: {}
- /unique-filename@2.0.1:
- resolution: {integrity: sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==}
- engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
+ strip-ansi@6.0.1:
dependencies:
- unique-slug: 3.0.0
- dev: true
+ ansi-regex: 5.0.1
+
+ strip-bom@3.0.0: {}
+
+ strip-json-comments@3.1.1: {}
- /unique-filename@3.0.0:
- resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+ strip-json-comments@5.0.3: {}
+
+ sucrase@3.35.1:
dependencies:
- unique-slug: 4.0.0
- dev: true
+ '@jridgewell/gen-mapping': 0.3.5
+ commander: 4.1.1
+ lines-and-columns: 1.2.4
+ mz: 2.7.0
+ pirates: 4.0.6
+ tinyglobby: 0.2.15
+ ts-interface-checker: 0.1.13
- /unique-slug@3.0.0:
- resolution: {integrity: sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==}
- engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
+ supports-color@7.2.0:
dependencies:
- imurmurhash: 0.1.4
- dev: true
+ has-flag: 4.0.0
- /unique-slug@4.0.0:
- resolution: {integrity: sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+ tar@7.5.16:
dependencies:
- imurmurhash: 0.1.4
- dev: true
+ '@isaacs/fs-minipass': 4.0.1
+ chownr: 3.0.0
+ minipass: 7.1.3
+ minizlib: 3.1.0
+ yallist: 5.0.0
- /unique-string@2.0.0:
- resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==}
- engines: {node: '>=8'}
+ text-table@0.2.0: {}
+
+ thenify-all@1.6.0:
dependencies:
- crypto-random-string: 2.0.0
- dev: true
+ thenify: 3.3.1
- /unique-string@3.0.0:
- resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==}
- engines: {node: '>=12'}
+ thenify@3.3.1:
dependencies:
- crypto-random-string: 4.0.0
- dev: true
+ any-promise: 1.3.0
- /universalify@0.1.2:
- resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
- engines: {node: '>= 4.0.0'}
- dev: true
+ tinybench@2.9.0: {}
- /universalify@2.0.1:
- resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
- engines: {node: '>= 10.0.0'}
- dev: true
+ tinyexec@0.3.2: {}
- /untildify@4.0.0:
- resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==}
- engines: {node: '>=8'}
- dev: true
+ tinyexec@1.2.4: {}
- /update-notifier@6.0.2:
- resolution: {integrity: sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==}
- engines: {node: '>=14.16'}
+ tinyglobby@0.2.15:
dependencies:
- boxen: 7.1.1
- chalk: 5.3.0
- configstore: 6.0.0
- has-yarn: 3.0.0
- import-lazy: 4.0.0
- is-ci: 3.0.1
- is-installed-globally: 0.4.0
- is-npm: 6.0.0
- is-yarn-global: 0.4.1
- latest-version: 7.0.0
- pupa: 3.1.0
- semver: 7.6.0
- semver-diff: 4.0.0
- xdg-basedir: 5.1.0
- dev: true
+ fdir: 6.5.0(picomatch@4.0.4)
+ picomatch: 4.0.4
- /utf-8-validate@6.0.3:
- resolution: {integrity: sha512-uIuGf9TWQ/y+0Lp+KGZCMuJWc3N9BHA+l/UmHd/oUHwJJDeysyTRxNQVkbzsIWfGFbRe3OcgML/i0mvVRPOyDA==}
- engines: {node: '>=6.14.2'}
- requiresBuild: true
+ tinyglobby@0.2.17:
dependencies:
- node-gyp-build: 4.8.0
- dev: false
+ fdir: 6.5.0(picomatch@4.0.4)
+ picomatch: 4.0.4
- /util-deprecate@1.0.2:
- resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
- dev: true
+ tinyrainbow@3.1.0: {}
- /validate-npm-package-license@3.0.4:
- resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
+ to-regex-range@5.0.1:
dependencies:
- spdx-correct: 3.2.0
- spdx-expression-parse: 3.0.1
- dev: true
-
- /validate-npm-package-name@4.0.0:
- resolution: {integrity: sha512-mzR0L8ZDktZjpX4OB46KT+56MAhl4EIazWP/+G/HPGuvfdaqg4YsCdtOm6U9+LOFyYDoh4dpnpxZRB9MQQns5Q==}
- engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
- dependencies:
- builtins: 5.0.1
- dev: true
+ is-number: 7.0.0
- /validate-npm-package-name@5.0.0:
- resolution: {integrity: sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- dependencies:
- builtins: 5.0.1
- dev: true
+ tree-kill@1.2.2: {}
- /version-selector-type@3.0.0:
- resolution: {integrity: sha512-PSvMIZS7C1MuVNBXl/CDG2pZq8EXy/NW2dHIdm3bVP5N0PC8utDK8ttXLXj44Gn3J0lQE3U7Mpm1estAOd+eiA==}
- engines: {node: '>=10.13'}
+ ts-api-utils@1.4.3(typescript@5.7.3):
dependencies:
- semver: 7.6.0
- dev: true
+ typescript: 5.7.3
- /vite-node@0.34.6(@types/node@18.19.26):
- resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==}
- engines: {node: '>=v14.18.0'}
- hasBin: true
- dependencies:
- cac: 6.7.14
- debug: 4.3.4
- mlly: 1.6.1
- pathe: 1.1.2
- picocolors: 1.0.0
- vite: 5.2.6(@types/node@18.19.26)
- transitivePeerDependencies:
- - '@types/node'
- - less
- - lightningcss
- - sass
- - stylus
- - sugarss
- - supports-color
- - terser
- dev: true
+ ts-interface-checker@0.1.13: {}
- /vite@5.2.6(@types/node@18.19.26):
- resolution: {integrity: sha512-FPtnxFlSIKYjZ2eosBQamz4CbyrTizbZ3hnGJlh/wMtCrlp1Hah6AzBLjGI5I2urTfNnpovpHdrL6YRuBOPnCA==}
- engines: {node: ^18.0.0 || >=20.0.0}
- hasBin: true
- peerDependencies:
- '@types/node': ^18.0.0 || >=20.0.0
- less: '*'
- lightningcss: ^1.21.0
- sass: '*'
- stylus: '*'
- sugarss: '*'
- terser: ^5.4.0
- peerDependenciesMeta:
- '@types/node':
- optional: true
- less:
- optional: true
- lightningcss:
- optional: true
- sass:
- optional: true
- stylus:
- optional: true
- sugarss:
- optional: true
- terser:
- optional: true
- dependencies:
- '@types/node': 18.19.26
- esbuild: 0.20.2
- postcss: 8.4.38
- rollup: 4.13.0
- optionalDependencies:
- fsevents: 2.3.3
- dev: true
+ tslib@2.8.1:
+ optional: true
- /vitest@0.34.6:
- resolution: {integrity: sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==}
- engines: {node: '>=v14.18.0'}
- hasBin: true
- peerDependencies:
- '@edge-runtime/vm': '*'
- '@vitest/browser': '*'
- '@vitest/ui': '*'
- happy-dom: '*'
- jsdom: '*'
- playwright: '*'
- safaridriver: '*'
- webdriverio: '*'
- peerDependenciesMeta:
- '@edge-runtime/vm':
- optional: true
- '@vitest/browser':
- optional: true
- '@vitest/ui':
- optional: true
- happy-dom:
- optional: true
- jsdom:
- optional: true
- playwright:
- optional: true
- safaridriver:
- optional: true
- webdriverio:
- optional: true
+ tsup@8.5.1(jiti@2.7.0)(postcss@8.5.15)(typescript@5.7.3)(yaml@2.9.0):
dependencies:
- '@types/chai': 4.3.14
- '@types/chai-subset': 1.3.5
- '@types/node': 18.19.26
- '@vitest/expect': 0.34.6
- '@vitest/runner': 0.34.6
- '@vitest/snapshot': 0.34.6
- '@vitest/spy': 0.34.6
- '@vitest/utils': 0.34.6
- acorn: 8.11.3
- acorn-walk: 8.3.2
+ bundle-require: 5.1.0(esbuild@0.27.2)
cac: 6.7.14
- chai: 4.4.1
- debug: 4.3.4
- local-pkg: 0.4.3
- magic-string: 0.30.8
- pathe: 1.1.2
- picocolors: 1.0.0
- std-env: 3.7.0
- strip-literal: 1.3.0
- tinybench: 2.6.0
- tinypool: 0.7.0
- vite: 5.2.6(@types/node@18.19.26)
- vite-node: 0.34.6(@types/node@18.19.26)
- why-is-node-running: 2.2.2
+ chokidar: 4.0.3
+ consola: 3.4.0
+ debug: 4.4.3
+ esbuild: 0.27.2
+ fix-dts-default-cjs-exports: 1.0.1
+ joycon: 3.1.1
+ picocolors: 1.1.1
+ postcss-load-config: 6.0.1(jiti@2.7.0)(postcss@8.5.15)(yaml@2.9.0)
+ resolve-from: 5.0.0
+ rollup: 4.39.0
+ source-map: 0.7.6
+ sucrase: 3.35.1
+ tinyexec: 0.3.2
+ tinyglobby: 0.2.15
+ tree-kill: 1.2.2
+ optionalDependencies:
+ postcss: 8.5.15
+ typescript: 5.7.3
transitivePeerDependencies:
- - less
- - lightningcss
- - sass
- - stylus
- - sugarss
+ - jiti
- supports-color
- - terser
- dev: true
+ - tsx
+ - yaml
- /vlq@0.2.3:
- resolution: {integrity: sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==}
- dev: true
-
- /wcwidth@1.0.1:
- resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==}
- requiresBuild: true
+ type-check@0.4.0:
dependencies:
- defaults: 1.0.4
- dev: true
+ prelude-ls: 1.2.1
- /webidl-conversions@4.0.2:
- resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==}
- dev: true
+ type-fest@0.20.2: {}
- /whatwg-url@7.1.0:
- resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==}
- dependencies:
- lodash.sortby: 4.7.0
- tr46: 1.0.1
- webidl-conversions: 4.0.2
- dev: true
+ typescript@5.7.3: {}
- /which-boxed-primitive@1.0.2:
- resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==}
- dependencies:
- is-bigint: 1.0.4
- is-boolean-object: 1.1.2
- is-number-object: 1.0.7
- is-string: 1.0.7
- is-symbol: 1.0.4
- dev: true
+ udc@1.0.1: {}
- /which-module@2.0.1:
- resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==}
- dev: true
+ ufo@1.6.1: {}
- /which-pm@2.0.0:
- resolution: {integrity: sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w==}
- engines: {node: '>=8.15'}
- dependencies:
- load-yaml-file: 0.2.0
- path-exists: 4.0.0
- dev: true
+ unbash@2.2.0: {}
- /which-typed-array@1.1.15:
- resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==}
- engines: {node: '>= 0.4'}
- dependencies:
- available-typed-arrays: 1.0.7
- call-bind: 1.0.7
- for-each: 0.3.3
- gopd: 1.0.1
- has-tostringtag: 1.0.2
- dev: true
+ underscore@1.13.6: {}
- /which@1.3.1:
- resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==}
- hasBin: true
- dependencies:
- isexe: 2.0.0
- dev: true
+ undici-types@6.21.0: {}
- /which@2.0.2:
- resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
- engines: {node: '>= 8'}
- hasBin: true
- dependencies:
- isexe: 2.0.0
- dev: true
+ undici@7.27.0: {}
- /which@3.0.1:
- resolution: {integrity: sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
- hasBin: true
- dependencies:
- isexe: 2.0.0
- dev: true
+ universalify@0.1.2: {}
- /why-is-node-running@2.2.2:
- resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==}
- engines: {node: '>=8'}
- hasBin: true
+ uri-js@4.4.1:
dependencies:
- siginfo: 2.0.0
- stackback: 0.0.2
- dev: true
+ punycode: 2.3.1
- /wide-align@1.1.5:
- resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==}
+ vite@7.3.2(@types/node@20.19.41)(jiti@2.7.0)(yaml@2.9.0):
dependencies:
- string-width: 4.2.3
- dev: true
+ esbuild: 0.27.7
+ fdir: 6.5.0(picomatch@4.0.4)
+ picomatch: 4.0.4
+ postcss: 8.5.15
+ rollup: 4.61.0
+ tinyglobby: 0.2.17
+ optionalDependencies:
+ '@types/node': 20.19.41
+ fsevents: 2.3.3
+ jiti: 2.7.0
+ yaml: 2.9.0
+
+ vitest@4.1.8(@types/node@20.19.41)(vite@7.3.2(@types/node@20.19.41)(jiti@2.7.0)(yaml@2.9.0)):
+ dependencies:
+ '@vitest/expect': 4.1.8
+ '@vitest/mocker': 4.1.8(vite@7.3.2(@types/node@20.19.41)(jiti@2.7.0)(yaml@2.9.0))
+ '@vitest/pretty-format': 4.1.8
+ '@vitest/runner': 4.1.8
+ '@vitest/snapshot': 4.1.8
+ '@vitest/spy': 4.1.8
+ '@vitest/utils': 4.1.8
+ es-module-lexer: 2.1.0
+ expect-type: 1.3.0
+ magic-string: 0.30.21
+ obug: 2.1.1
+ pathe: 2.0.3
+ picomatch: 4.0.4
+ std-env: 4.1.0
+ tinybench: 2.9.0
+ tinyexec: 1.2.4
+ tinyglobby: 0.2.17
+ tinyrainbow: 3.1.0
+ vite: 7.3.2(@types/node@20.19.41)(jiti@2.7.0)(yaml@2.9.0)
+ why-is-node-running: 2.3.0
+ optionalDependencies:
+ '@types/node': 20.19.41
+ transitivePeerDependencies:
+ - msw
- /widest-line@4.0.1:
- resolution: {integrity: sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==}
- engines: {node: '>=12'}
- dependencies:
- string-width: 5.1.2
- dev: true
+ vscode-languageserver-textdocument@1.0.12: {}
- /wrap-ansi@6.2.0:
- resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
- engines: {node: '>=8'}
- dependencies:
- ansi-styles: 4.3.0
- string-width: 4.2.3
- strip-ansi: 6.0.1
- dev: true
+ vscode-languageserver-types@3.18.0: {}
- /wrap-ansi@7.0.0:
- resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
- engines: {node: '>=10'}
- dependencies:
- ansi-styles: 4.3.0
- string-width: 4.2.3
- strip-ansi: 6.0.1
- dev: true
+ walk-up-path@4.0.0: {}
- /wrap-ansi@8.1.0:
- resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
- engines: {node: '>=12'}
+ which@2.0.2:
dependencies:
- ansi-styles: 6.2.1
- string-width: 5.1.2
- strip-ansi: 7.1.0
- dev: true
-
- /wrappy@1.0.2:
- resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
- dev: true
+ isexe: 2.0.0
- /write-file-atomic@3.0.3:
- resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==}
- dependencies:
- imurmurhash: 0.1.4
- is-typedarray: 1.0.0
- signal-exit: 3.0.7
- typedarray-to-buffer: 3.1.5
- dev: true
-
- /ws@8.16.0(bufferutil@4.0.8)(utf-8-validate@6.0.3):
- resolution: {integrity: sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==}
- engines: {node: '>=10.0.0'}
- peerDependencies:
- bufferutil: ^4.0.1
- utf-8-validate: '>=5.0.2'
- peerDependenciesMeta:
- bufferutil:
- optional: true
- utf-8-validate:
- optional: true
+ why-is-node-running@2.3.0:
dependencies:
- bufferutil: 4.0.8
- utf-8-validate: 6.0.3
- dev: false
-
- /xdg-basedir@5.1.0:
- resolution: {integrity: sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==}
- engines: {node: '>=12'}
- dev: true
-
- /y18n@4.0.3:
- resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==}
- dev: true
-
- /y18n@5.0.8:
- resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
- engines: {node: '>=10'}
- dev: true
-
- /yallist@2.1.2:
- resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==}
- dev: true
-
- /yallist@4.0.0:
- resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
- dev: true
-
- /yaml@1.10.2:
- resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
- engines: {node: '>= 6'}
- dev: true
+ siginfo: 2.0.0
+ stackback: 0.0.2
- /yargs-parser@18.1.3:
- resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==}
- engines: {node: '>=6'}
- dependencies:
- camelcase: 5.3.1
- decamelize: 1.2.0
- dev: true
+ word-wrap@1.2.5: {}
- /yargs-parser@21.1.1:
- resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
- engines: {node: '>=12'}
- dev: true
+ wrappy@1.0.2: {}
- /yargs@15.4.1:
- resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==}
- engines: {node: '>=8'}
- dependencies:
- cliui: 6.0.0
- decamelize: 1.2.0
- find-up: 4.1.0
- get-caller-file: 2.0.5
- require-directory: 2.1.1
- require-main-filename: 2.0.0
- set-blocking: 2.0.0
- string-width: 4.2.3
- which-module: 2.0.1
- y18n: 4.0.3
- yargs-parser: 18.1.3
- dev: true
-
- /yargs@17.7.2:
- resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
- engines: {node: '>=12'}
- dependencies:
- cliui: 8.0.1
- escalade: 3.1.2
- get-caller-file: 2.0.5
- require-directory: 2.1.1
- string-width: 4.2.3
- y18n: 5.0.8
- yargs-parser: 21.1.1
- dev: true
+ yallist@4.0.0: {}
- /yocto-queue@0.1.0:
- resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
- engines: {node: '>=10'}
- dev: true
+ yallist@5.0.0: {}
- /yocto-queue@1.0.0:
- resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==}
- engines: {node: '>=12.20'}
- dev: true
+ yaml@2.9.0: {}
- /zod-validation-error@1.5.0(zod@3.22.4):
- resolution: {integrity: sha512-/7eFkAI4qV0tcxMBB/3+d2c1P6jzzZYdYSlBuAklzMuCrJu5bzJfHS0yVAS87dRHVlhftd6RFJDIvv03JgkSbw==}
- engines: {node: '>=16.0.0'}
- peerDependencies:
- zod: ^3.18.0
- dependencies:
- zod: 3.22.4
- dev: true
+ yocto-queue@0.1.0: {}
- /zod@3.22.4:
- resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==}
- dev: true
+ zod@4.4.3: {}
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index c9a0a34e..57e95728 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -1,3 +1,5 @@
packages:
- js
- python
+ - chart_data_extractor
+ - template
diff --git a/python/LICENSE b/python/LICENSE
new file mode 100644
index 00000000..4aa6529d
--- /dev/null
+++ b/python/LICENSE
@@ -0,0 +1,9 @@
+MIT License
+
+Copyright (c) 2025 FOUNDRYLABS, INC.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/python/README.md b/python/README.md
index 92b44bbc..aec65804 100644
--- a/python/README.md
+++ b/python/README.md
@@ -1,90 +1,49 @@
-# Code interpreter extension for Python
+
+
+
-The repository contains a template and modules for the code interpreter sandbox. It is based on the Jupyter server and implements the Jupyter Kernel messaging protocol. This allows for sharing context between code executions and improves support for plotting charts and other display-able data.
+
-## Key Features
+
+## What is E2B?
+[E2B](https://www.e2b.dev/) is an open-source infrastructure that allows you run to AI-generated code in secure isolated sandboxes in the cloud. To start and control sandboxes, use our [JavaScript SDK](https://www.npmjs.com/package/@e2b/code-interpreter) or [Python SDK](https://pypi.org/project/e2b_code_interpreter).
-- **Stateful Execution**: Unlike traditional sandboxes that treat each code execution independently, this package maintains context across executions.
-- **Displaying Graph & Data**: Implements parts of the [Jupyter Kernel messaging protocol](https://jupyter-client.readthedocs.io/en/latest/messaging.html), which support for interactive features like plotting charts, rendering DataFrames, etc.
+## Run your first Sandbox
-## Installation
+### 1. Install SDK
-```sh
+```
pip install e2b-code-interpreter
```
-## Examples
-
-### Minimal example with the sharing context
-
-```python
-from e2b_code_interpreter import CodeInterpreter
-
-with CodeInterpreter() as sandbox:
- sandbox.notebook.exec_cell("x = 1")
-
- execution = sandbox.notebook.exec_cell("x+=1; x")
- print(execution.text) # outputs 2
-
+### 2. Get your E2B API key
+1. Sign up to E2B [here](https://e2b.dev).
+2. Get your API key [here](https://e2b.dev/dashboard?tab=keys).
+3. Set environment variable with your API key.
```
+E2B_API_KEY=e2b_***
+```
-### Get charts and any display-able data
-
-```python
-import base64
-import io
-
-from matplotlib import image as mpimg, pyplot as plt
-
-from e2b_code_interpreter import CodeInterpreter
-
-code = """
-import matplotlib.pyplot as plt
-import numpy as np
+### 3. Execute code with code interpreter inside Sandbox
-x = np.linspace(0, 20, 100)
-y = np.sin(x)
+```py
+from e2b_code_interpreter import Sandbox
-plt.plot(x, y)
-plt.show()
-"""
-
-with CodeInterpreter() as sandbox:
- # you can install dependencies in "jupyter notebook style"
- sandbox.notebook.exec_cell("!pip install matplotlib")
-
- # plot random graph
- execution = sandbox.notebook.exec_cell(code)
-
-# there's your image
-image = execution.results[0].png
-
-# example how to show the image / prove it works
-i = base64.b64decode(image)
-i = io.BytesIO(i)
-i = mpimg.imread(i, format='PNG')
-
-plt.imshow(i, interpolation='nearest')
-plt.show()
+with Sandbox.create() as sandbox:
+ sandbox.run_code("x = 1")
+ execution = sandbox.run_code("x+=1; x")
+ print(execution.text) # outputs 2
```
-### Streaming code output
-
-```python
-from e2b_code_interpreter import CodeInterpreter
-
-code = """
-import time
-import pandas as pd
+### 4. Check docs
+Visit [E2B documentation](https://e2b.dev/docs).
-print("hello")
-time.sleep(3)
-data = pd.DataFrame(data=[[1, 2], [3, 4]], columns=["A", "B"])
-display(data.head(10))
-time.sleep(3)
-print("world")
-"""
-
-with CodeInterpreter() as sandbox:
- sandbox.notebook.exec_cell(code, on_stdout=print, on_stderr=print, on_result=(lambda result: print(result.text)))
-```
+### 5. E2B cookbook
+Visit our [Cookbook](https://github.com/e2b-dev/e2b-cookbook/tree/main) to get inspired by examples with different LLMs and AI frameworks.
diff --git a/python/async_example.py b/python/async_example.py
new file mode 100644
index 00000000..0f7dd78b
--- /dev/null
+++ b/python/async_example.py
@@ -0,0 +1,68 @@
+import asyncio
+
+from dotenv import load_dotenv
+
+from e2b_code_interpreter import AsyncSandbox
+
+load_dotenv()
+
+code = """
+import matplotlib.pyplot as plt
+import numpy as np
+
+# Data for plotting
+x = np.linspace(0, 10, 100)
+y1 = np.sin(x)
+y2 = np.cos(x)
+y3 = x**2
+y4 = np.sqrt(x)
+
+# Create a figure with multiple subplots
+fig, axs = plt.subplots(2, 2, figsize=(10, 8))
+
+# Plotting on the different axes
+axs[0, 0].plot(x, y1, 'r')
+axs[0, 0].set_title('Sine Wave')
+axs[0, 0].grid(True)
+
+axs[0, 1].plot(x, y2, 'b')
+axs[0, 1].set_title('Cosine Wave')
+axs[0, 1].grid(True)
+
+axs[1, 0].plot(x, y3, 'g')
+axs[1, 0].set_title('Quadratic Function')
+axs[1, 0].grid(True)
+
+axs[1, 1].plot(x, y4, 'm')
+axs[1, 1].set_title('Square Root Function')
+axs[1, 1].grid(True)
+
+# Adjust layout to prevent overlap
+plt.tight_layout()
+
+# Display the figure
+plt.show()
+"""
+
+
+async def create_sbx(sbx, i: int):
+ await asyncio.sleep(i * 0.01)
+ return (await sbx.run_code("os.getenv('TEST')", envs={"TEST": str(i)})).text
+
+
+async def run():
+ sbx = await AsyncSandbox.create(debug=True)
+ result = await sbx.run_code(code)
+
+ print("".join(result.logs.stdout))
+ print("".join(result.logs.stderr))
+ if result.error:
+ print(result.error.traceback)
+
+ print(result.results[0].formats())
+ print(result.results[0].elements.elements)
+
+ await sbx.kill()
+
+
+asyncio.run(run())
diff --git a/python/e2b_code_interpreter/__init__.py b/python/e2b_code_interpreter/__init__.py
index aa04c93d..5202d5de 100644
--- a/python/e2b_code_interpreter/__init__.py
+++ b/python/e2b_code_interpreter/__init__.py
@@ -1,4 +1,14 @@
from e2b import *
-
-from .main import CodeInterpreter, JupyterExtension
-from .models import Execution, Error, Result, KernelException, MIMEType, Logs
+from .code_interpreter_sync import Sandbox
+from .code_interpreter_async import AsyncSandbox
+from .models import (
+ Context,
+ Execution,
+ ExecutionError,
+ Result,
+ MIMEType,
+ Logs,
+ OutputHandler,
+ OutputMessage,
+ RunCodeLanguage,
+)
diff --git a/python/e2b_code_interpreter/charts.py b/python/e2b_code_interpreter/charts.py
new file mode 100644
index 00000000..8ccb798d
--- /dev/null
+++ b/python/e2b_code_interpreter/charts.py
@@ -0,0 +1,230 @@
+import enum
+from typing import Any, List, Tuple, Optional, Union
+
+
+class ChartType(str, enum.Enum):
+ """
+ Chart types
+ """
+
+ LINE = "line"
+ SCATTER = "scatter"
+ BAR = "bar"
+ PIE = "pie"
+ BOX_AND_WHISKER = "box_and_whisker"
+ SUPERCHART = "superchart"
+ UNKNOWN = "unknown"
+
+
+class ScaleType(str, enum.Enum):
+ """
+ Ax scale types
+ """
+
+ LINEAR = "linear"
+ DATETIME = "datetime"
+ CATEGORICAL = "categorical"
+ LOG = "log"
+ SYMLOG = "symlog"
+ LOGIT = "logit"
+ FUNCTION = "function"
+ FUNCTIONLOG = "functionlog"
+ ASINH = "asinh"
+ UNKNOWN = "unknown"
+
+
+class Chart:
+ """
+ Extracted data from a chart. It's useful for building an interactive charts or custom visualizations.
+ """
+
+ type: ChartType
+ title: str
+
+ elements: List[Any]
+
+ def __init__(self, **kwargs):
+ self._raw_data = kwargs
+ self.type = ChartType(kwargs["type"] or ChartType.UNKNOWN)
+ self.title = kwargs["title"]
+ self.elements = kwargs["elements"]
+
+ def to_dict(self) -> dict:
+ return self._raw_data
+
+
+class Chart2D(Chart):
+ x_label: Optional[str]
+ y_label: Optional[str]
+ x_unit: Optional[str]
+ y_unit: Optional[str]
+
+ def __init__(self, **kwargs):
+ super().__init__(**kwargs)
+ self.x_label = kwargs["x_label"]
+ self.y_label = kwargs["y_label"]
+ self.x_unit = kwargs["x_unit"]
+ self.y_unit = kwargs["y_unit"]
+
+
+class PointData:
+ label: str
+ points: List[Tuple[Union[str, float], Union[str, float]]]
+
+ def __init__(self, **kwargs):
+ self.label = kwargs["label"]
+ self.points = [(x, y) for x, y in kwargs["points"]]
+
+
+class PointChart(Chart2D):
+ x_ticks: List[Union[str, float]]
+ x_tick_labels: List[str]
+ x_scale: ScaleType
+
+ y_ticks: List[Union[str, float]]
+ y_tick_labels: List[str]
+ y_scale: ScaleType
+
+ elements: List[PointData]
+
+ def __init__(self, **kwargs):
+ super().__init__(**kwargs)
+ self.x_label = kwargs["x_label"]
+
+ try:
+ self.x_scale = ScaleType(kwargs.get("x_scale"))
+ except ValueError:
+ self.x_scale = ScaleType.UNKNOWN
+
+ self.x_ticks = kwargs["x_ticks"]
+ self.x_tick_labels = kwargs["x_tick_labels"]
+
+ self.y_label = kwargs["y_label"]
+
+ try:
+ self.y_scale = ScaleType(kwargs.get("y_scale"))
+ except ValueError:
+ self.y_scale = ScaleType.UNKNOWN
+
+ self.y_ticks = kwargs["y_ticks"]
+ self.y_tick_labels = kwargs["y_tick_labels"]
+
+ self.elements = [PointData(**d) for d in kwargs["elements"]]
+
+
+class LineChart(PointChart):
+ type = ChartType.LINE
+
+
+class ScatterChart(PointChart):
+ type = ChartType.SCATTER
+
+
+class BarData:
+ label: str
+ group: str
+ value: str
+
+ def __init__(self, **kwargs):
+ self.label = kwargs["label"]
+ self.value = kwargs["value"]
+ self.group = kwargs["group"]
+
+
+class BarChart(Chart2D):
+ type = ChartType.BAR
+
+ elements: List[BarData]
+
+ def __init__(self, **kwargs):
+ super().__init__(**kwargs)
+ self.elements = [BarData(**d) for d in kwargs["elements"]]
+
+
+class PieData:
+ label: str
+ angle: float
+ radius: float
+
+ def __init__(self, **kwargs):
+ self.label = kwargs["label"]
+ self.angle = kwargs["angle"]
+ self.radius = kwargs["radius"]
+
+
+class PieChart(Chart):
+ type = ChartType.PIE
+
+ elements: List[PieData]
+
+ def __init__(self, **kwargs):
+ super().__init__(**kwargs)
+ self.elements = [PieData(**d) for d in kwargs["elements"]]
+
+
+class BoxAndWhiskerData:
+ label: str
+ min: float
+ first_quartile: float
+ median: float
+ third_quartile: float
+ max: float
+ outliers: List[float]
+
+ def __init__(self, **kwargs):
+ self.label = kwargs["label"]
+ self.min = kwargs["min"]
+ self.first_quartile = kwargs["first_quartile"]
+ self.median = kwargs["median"]
+ self.third_quartile = kwargs["third_quartile"]
+ self.max = kwargs["max"]
+ self.outliers = kwargs.get("outliers") or []
+
+
+class BoxAndWhiskerChart(Chart2D):
+ type = ChartType.BOX_AND_WHISKER
+
+ elements: List[BoxAndWhiskerData]
+
+ def __init__(self, **kwargs):
+ super().__init__(**kwargs)
+ self.elements = [BoxAndWhiskerData(**d) for d in kwargs["elements"]]
+
+
+class SuperChart(Chart):
+ type = ChartType.SUPERCHART
+
+ elements: List[
+ Union[LineChart, ScatterChart, BarChart, PieChart, BoxAndWhiskerChart]
+ ]
+
+ def __init__(self, **kwargs):
+ super().__init__(**kwargs)
+ self.elements = [_deserialize_chart(g) for g in kwargs["elements"]]
+
+
+ChartTypes = Union[
+ LineChart, ScatterChart, BarChart, PieChart, BoxAndWhiskerChart, SuperChart
+]
+
+
+def _deserialize_chart(data: Optional[dict]) -> Optional[ChartTypes]:
+ if not data:
+ return None
+
+ if data["type"] == ChartType.LINE:
+ chart = LineChart(**data)
+ elif data["type"] == ChartType.SCATTER:
+ chart = ScatterChart(**data)
+ elif data["type"] == ChartType.BAR:
+ chart = BarChart(**data)
+ elif data["type"] == ChartType.PIE:
+ chart = PieChart(**data)
+ elif data["type"] == ChartType.BOX_AND_WHISKER:
+ chart = BoxAndWhiskerChart(**data)
+ elif data["type"] == ChartType.SUPERCHART:
+ chart = SuperChart(**data)
+ else:
+ chart = Chart(**data)
+
+ return chart
diff --git a/python/e2b_code_interpreter/code_interpreter_async.py b/python/e2b_code_interpreter/code_interpreter_async.py
new file mode 100644
index 00000000..4f3696c4
--- /dev/null
+++ b/python/e2b_code_interpreter/code_interpreter_async.py
@@ -0,0 +1,356 @@
+import logging
+import httpx
+
+from typing import Optional, Dict, overload, Union, List
+from httpx import AsyncClient
+
+from e2b import (
+ AsyncSandbox as BaseAsyncSandbox,
+ InvalidArgumentException,
+)
+from e2b.api.client_async import get_transport
+
+from e2b_code_interpreter.constants import (
+ DEFAULT_TEMPLATE,
+ JUPYTER_PORT,
+ DEFAULT_TIMEOUT,
+)
+from e2b_code_interpreter.models import (
+ Execution,
+ ExecutionError,
+ Context,
+ RunCodeLanguage,
+ Result,
+ aextract_exception,
+ OutputHandlerWithAsync,
+ async_parse_output,
+ OutputMessage,
+)
+from e2b_code_interpreter.exceptions import (
+ format_execution_timeout_error,
+ format_request_timeout_error,
+)
+
+logger = logging.getLogger(__name__)
+
+
+class AsyncSandbox(BaseAsyncSandbox):
+ """
+ E2B cloud sandbox is a secure and isolated cloud environment.
+
+ The sandbox allows you to:
+ - Access Linux OS
+ - Create, list, and delete files and directories
+ - Run commands
+ - Run isolated code
+ - Access the internet
+
+ Check docs [here](https://e2b.dev/docs).
+
+ Use the `AsyncSandbox.create()` to create a new sandbox.
+
+ Example:
+ ```python
+ from e2b_code_interpreter import AsyncSandbox
+ sandbox = await AsyncSandbox.create()
+ ```
+ """
+
+ default_template = DEFAULT_TEMPLATE
+
+ @property
+ def _jupyter_url(self) -> str:
+ return f"{'http' if self.connection_config.debug else 'https'}://{self.get_host(JUPYTER_PORT)}"
+
+ @property
+ def _client(self) -> AsyncClient:
+ # TODO: Remove later
+ # Use a dedicated HTTP/1.1 transport for Jupyter requests.
+ #
+ # The base SDK's shared transport now defaults to http2=True. With
+ # HTTP/2, multiple requests are multiplexed over a single TCP
+ # connection, so when a client cancels a request (e.g. the caller
+ # disconnects from the streaming `/execute` endpoint) the server
+ # may not detect the disconnect: only the HTTP/2 stream is
+ # cancelled, the underlying TCP connection stays open.
+ #
+ # Forcing HTTP/1.1 here keeps the 1:1 mapping between TCP
+ # connection and request, so client disconnects propagate to the
+ # server as a TCP close and long-running executions can be
+ # cancelled reliably. The helper also caches the transport
+ # per-event-loop for async.
+ return AsyncClient(
+ transport=get_transport(self.connection_config, http2=False),
+ )
+
+ @overload
+ async def run_code(
+ self,
+ code: str,
+ language: Optional[RunCodeLanguage] = None,
+ on_stdout: Optional[OutputHandlerWithAsync[OutputMessage]] = None,
+ on_stderr: Optional[OutputHandlerWithAsync[OutputMessage]] = None,
+ on_result: Optional[OutputHandlerWithAsync[Result]] = None,
+ on_error: Optional[OutputHandlerWithAsync[ExecutionError]] = None,
+ envs: Optional[Dict[str, str]] = None,
+ timeout: Optional[float] = None,
+ request_timeout: Optional[float] = None,
+ ) -> Execution:
+ """
+ Runs the code for the specified language.
+
+ Specify the `language` or `context` option to run the code as a different language or in a different `Context`.
+ If no language is specified, Python is used.
+
+ You can reference previously defined variables, imports, and functions in the code.
+
+ :param code: Code to execute
+ :param language: Language to use for code execution. If not defined, the default Python context is used.
+ :param on_stdout: Callback for stdout messages
+ :param on_stderr: Callback for stderr messages
+ :param on_result: Callback for the `Result` object
+ :param on_error: Callback for the `ExecutionError` object
+ :param envs: Custom environment variables
+ :param timeout: Timeout for the code execution in **seconds**
+ :param request_timeout: Timeout for the request in **seconds**
+
+ :return: `Execution` result object
+ """
+ ...
+
+ @overload
+ async def run_code(
+ self,
+ code: str,
+ context: Optional[Context] = None,
+ on_stdout: Optional[OutputHandlerWithAsync[OutputMessage]] = None,
+ on_stderr: Optional[OutputHandlerWithAsync[OutputMessage]] = None,
+ on_result: Optional[OutputHandlerWithAsync[Result]] = None,
+ on_error: Optional[OutputHandlerWithAsync[ExecutionError]] = None,
+ envs: Optional[Dict[str, str]] = None,
+ timeout: Optional[float] = None,
+ request_timeout: Optional[float] = None,
+ ) -> Execution:
+ """
+ Runs the code in the specified context, if not specified, the default context is used.
+
+ Specify the `language` or `context` option to run the code as a different language or in a different `Context`.
+
+ You can reference previously defined variables, imports, and functions in the code.
+
+ :param code: Code to execute
+ :param context: Concrete context to run the code in. If not specified, the default context for the language is used. It's mutually exclusive with the language.
+ :param on_stdout: Callback for stdout messages
+ :param on_stderr: Callback for stderr messages
+ :param on_result: Callback for the `Result` object
+ :param on_error: Callback for the `ExecutionError` object
+ :param envs: Custom environment variables
+ :param timeout: Timeout for the code execution in **seconds**
+ :param request_timeout: Timeout for the request in **seconds**
+
+ :return: `Execution` result object
+ """
+ ...
+
+ async def run_code(
+ self,
+ code: str,
+ language: Optional[str] = None,
+ context: Optional[Context] = None,
+ on_stdout: Optional[OutputHandlerWithAsync[OutputMessage]] = None,
+ on_stderr: Optional[OutputHandlerWithAsync[OutputMessage]] = None,
+ on_result: Optional[OutputHandlerWithAsync[Result]] = None,
+ on_error: Optional[OutputHandlerWithAsync[ExecutionError]] = None,
+ envs: Optional[Dict[str, str]] = None,
+ timeout: Optional[float] = None,
+ request_timeout: Optional[float] = None,
+ ) -> Execution:
+ logger.debug(f"Executing code {code}")
+
+ if context and language:
+ raise InvalidArgumentException(
+ "You can provide context or language, but not both at the same time."
+ )
+
+ timeout = None if timeout == 0 else (timeout or DEFAULT_TIMEOUT)
+ request_timeout = request_timeout or self.connection_config.request_timeout
+ context_id = context.id if context else None
+ try:
+ headers = {
+ "Content-Type": "application/json",
+ }
+ if self._envd_access_token:
+ headers["X-Access-Token"] = self._envd_access_token
+ if self.traffic_access_token:
+ headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
+
+ async with self._client.stream(
+ "POST",
+ f"{self._jupyter_url}/execute",
+ json={
+ "code": code,
+ "context_id": context_id,
+ "language": language,
+ "env_vars": envs,
+ },
+ headers=headers,
+ timeout=(request_timeout, timeout, request_timeout, request_timeout),
+ ) as response:
+ err = await aextract_exception(response)
+ if err:
+ raise err
+
+ execution = Execution()
+
+ async for line in response.aiter_lines():
+ await async_parse_output(
+ execution,
+ line,
+ on_stdout=on_stdout,
+ on_stderr=on_stderr,
+ on_result=on_result,
+ on_error=on_error,
+ )
+
+ return execution
+ except httpx.ReadTimeout:
+ raise format_execution_timeout_error()
+ except httpx.TimeoutException:
+ raise format_request_timeout_error()
+
+ async def create_code_context(
+ self,
+ cwd: Optional[str] = None,
+ language: Optional[RunCodeLanguage] = None,
+ request_timeout: Optional[float] = None,
+ ) -> Context:
+ """
+ Creates a new context to run code in.
+
+ :param cwd: Set the current working directory for the context, defaults to `/home/user`
+ :param language: Language of the context. If not specified, defaults to Python
+ :param request_timeout: Timeout for the request in **milliseconds**
+
+ :return: Context object
+ """
+ logger.debug(f"Creating new {language} context")
+
+ data = {}
+ if language:
+ data["language"] = language
+ if cwd:
+ data["cwd"] = cwd
+
+ try:
+ headers = {
+ "Content-Type": "application/json",
+ }
+ if self.traffic_access_token:
+ headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
+
+ response = await self._client.post(
+ f"{self._jupyter_url}/contexts",
+ headers=headers,
+ json=data,
+ timeout=request_timeout or self.connection_config.request_timeout,
+ )
+
+ err = await aextract_exception(response)
+ if err:
+ raise err
+
+ data = response.json()
+ return Context.from_json(data)
+ except httpx.TimeoutException:
+ raise format_request_timeout_error()
+
+ async def remove_code_context(
+ self,
+ context: Union[Context, str],
+ ) -> None:
+ """
+ Removes a context.
+
+ :param context: Context to remove. Can be a Context object or a context ID string.
+
+ :return: None
+ """
+ context_id = context.id if isinstance(context, Context) else context
+
+ try:
+ headers = {
+ "Content-Type": "application/json",
+ }
+ if self.traffic_access_token:
+ headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
+
+ response = await self._client.delete(
+ f"{self._jupyter_url}/contexts/{context_id}",
+ headers=headers,
+ timeout=self.connection_config.request_timeout,
+ )
+
+ err = await aextract_exception(response)
+ if err:
+ raise err
+ except httpx.TimeoutException:
+ raise format_request_timeout_error()
+
+ async def list_code_contexts(self) -> List[Context]:
+ """
+ List all contexts.
+
+ :return: List of contexts.
+ """
+ try:
+ headers = {
+ "Content-Type": "application/json",
+ }
+ if self.traffic_access_token:
+ headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
+
+ response = await self._client.get(
+ f"{self._jupyter_url}/contexts",
+ headers=headers,
+ timeout=self.connection_config.request_timeout,
+ )
+
+ err = await aextract_exception(response)
+ if err:
+ raise err
+
+ data = response.json()
+ return [Context.from_json(context_data) for context_data in data]
+ except httpx.TimeoutException:
+ raise format_request_timeout_error()
+
+ async def restart_code_context(
+ self,
+ context: Union[Context, str],
+ ) -> None:
+ """
+ Restart a context.
+
+ :param context: Context to restart. Can be a Context object or a context ID string.
+
+ :return: None
+ """
+ context_id = context.id if isinstance(context, Context) else context
+ try:
+ headers = {
+ "Content-Type": "application/json",
+ }
+ if self.traffic_access_token:
+ headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
+
+ response = await self._client.post(
+ f"{self._jupyter_url}/contexts/{context_id}/restart",
+ headers=headers,
+ timeout=self.connection_config.request_timeout,
+ )
+
+ err = await aextract_exception(response)
+ if err:
+ raise err
+ except httpx.TimeoutException:
+ raise format_request_timeout_error()
diff --git a/python/e2b_code_interpreter/code_interpreter_sync.py b/python/e2b_code_interpreter/code_interpreter_sync.py
new file mode 100644
index 00000000..bea57db4
--- /dev/null
+++ b/python/e2b_code_interpreter/code_interpreter_sync.py
@@ -0,0 +1,350 @@
+import logging
+import httpx
+
+from typing import Optional, Dict, overload, Union, List
+from httpx import Client
+from e2b import Sandbox as BaseSandbox, InvalidArgumentException
+from e2b.api.client_sync import get_transport
+
+from e2b_code_interpreter.constants import (
+ DEFAULT_TEMPLATE,
+ JUPYTER_PORT,
+ DEFAULT_TIMEOUT,
+)
+from e2b_code_interpreter.models import (
+ ExecutionError,
+ Execution,
+ RunCodeLanguage,
+ Context,
+ Result,
+ extract_exception,
+ parse_output,
+ OutputHandler,
+ OutputMessage,
+)
+from e2b_code_interpreter.exceptions import (
+ format_execution_timeout_error,
+ format_request_timeout_error,
+)
+
+logger = logging.getLogger(__name__)
+
+
+class Sandbox(BaseSandbox):
+ """
+ E2B cloud sandbox is a secure and isolated cloud environment.
+
+ The sandbox allows you to:
+ - Access Linux OS
+ - Create, list, and delete files and directories
+ - Run commands
+ - Run isolated code
+ - Access the internet
+
+ Check docs [here](https://e2b.dev/docs).
+
+ Use the `Sandbox.create()` to create a new sandbox.
+
+ Example:
+ ```python
+ from e2b_code_interpreter import Sandbox
+
+ sandbox = Sandbox.create()
+ ```
+ """
+
+ default_template = DEFAULT_TEMPLATE
+
+ @property
+ def _jupyter_url(self) -> str:
+ return f"{'http' if self.connection_config.debug else 'https'}://{self.get_host(JUPYTER_PORT)}"
+
+ @property
+ def _client(self) -> Client:
+ # TODO: Remove later
+ # Use a dedicated HTTP/1.1 transport for Jupyter requests.
+ #
+ # The base SDK's shared transport now defaults to http2=True. With
+ # HTTP/2, multiple requests are multiplexed over a single TCP
+ # connection, so when a client cancels a request (e.g. the caller
+ # disconnects from the streaming `/execute` endpoint) the server
+ # may not detect the disconnect: only the HTTP/2 stream is
+ # cancelled, the underlying TCP connection stays open.
+ #
+ # Forcing HTTP/1.1 here keeps the 1:1 mapping between TCP
+ # connection and request, so client disconnects propagate to the
+ # server as a TCP close and long-running executions can be
+ # cancelled reliably.
+ return Client(transport=get_transport(self.connection_config, http2=False))
+
+ @overload
+ def run_code(
+ self,
+ code: str,
+ language: Optional[RunCodeLanguage] = None,
+ on_stdout: Optional[OutputHandler[OutputMessage]] = None,
+ on_stderr: Optional[OutputHandler[OutputMessage]] = None,
+ on_result: Optional[OutputHandler[Result]] = None,
+ on_error: Optional[OutputHandler[ExecutionError]] = None,
+ envs: Optional[Dict[str, str]] = None,
+ timeout: Optional[float] = None,
+ request_timeout: Optional[float] = None,
+ ) -> Execution:
+ """
+ Runs the code for the specified language.
+
+ Specify the `language` or `context` option to run the code as a different language or in a different `Context`.
+ If no language is specified, Python is used.
+
+ You can reference previously defined variables, imports, and functions in the code.
+
+ :param code: Code to execute
+ :param language: Language to use for code execution. If not defined, the default Python context is used.
+ :param on_stdout: Callback for stdout messages
+ :param on_stderr: Callback for stderr messages
+ :param on_result: Callback for the `Result` object
+ :param on_error: Callback for the `ExecutionError` object
+ :param envs: Custom environment variables
+ :param timeout: Timeout for the code execution in **seconds**
+ :param request_timeout: Timeout for the request in **seconds**
+
+ :return: `Execution` result object
+ """
+ ...
+
+ @overload
+ def run_code(
+ self,
+ code: str,
+ context: Optional[Context] = None,
+ on_stdout: Optional[OutputHandler[OutputMessage]] = None,
+ on_stderr: Optional[OutputHandler[OutputMessage]] = None,
+ on_result: Optional[OutputHandler[Result]] = None,
+ on_error: Optional[OutputHandler[ExecutionError]] = None,
+ envs: Optional[Dict[str, str]] = None,
+ timeout: Optional[float] = None,
+ request_timeout: Optional[float] = None,
+ ) -> Execution:
+ """
+ Runs the code in the specified context, if not specified, the default context is used.
+
+ Specify the `language` or `context` option to run the code as a different language or in a different `Context`.
+
+ You can reference previously defined variables, imports, and functions in the code.
+
+ :param code: Code to execute
+ :param context: Concrete context to run the code in. If not specified, the default context for the language is used. It's mutually exclusive with the language.
+ :param on_stdout: Callback for stdout messages
+ :param on_stderr: Callback for stderr messages
+ :param on_result: Callback for the `Result` object
+ :param on_error: Callback for the `ExecutionError` object
+ :param envs: Custom environment variables
+ :param timeout: Timeout for the code execution in **seconds**
+ :param request_timeout: Timeout for the request in **seconds**
+
+ :return: `Execution` result object
+ """
+ ...
+
+ def run_code(
+ self,
+ code: str,
+ language: Optional[str] = None,
+ context: Optional[Context] = None,
+ on_stdout: Optional[OutputHandler[OutputMessage]] = None,
+ on_stderr: Optional[OutputHandler[OutputMessage]] = None,
+ on_result: Optional[OutputHandler[Result]] = None,
+ on_error: Optional[OutputHandler[ExecutionError]] = None,
+ envs: Optional[Dict[str, str]] = None,
+ timeout: Optional[float] = None,
+ request_timeout: Optional[float] = None,
+ ) -> Execution:
+ logger.debug(f"Executing code {code}")
+
+ if language and context:
+ raise InvalidArgumentException(
+ "You can provide context or language, but not both at the same time."
+ )
+
+ timeout = None if timeout == 0 else (timeout or DEFAULT_TIMEOUT)
+ request_timeout = request_timeout or self.connection_config.request_timeout
+ context_id = context.id if context else None
+
+ try:
+ headers: Dict[str, str] = {"Content-Type": "application/json"}
+ if self._envd_access_token:
+ headers["X-Access-Token"] = self._envd_access_token
+ if self.traffic_access_token:
+ headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
+
+ with self._client.stream(
+ "POST",
+ f"{self._jupyter_url}/execute",
+ json={
+ "code": code,
+ "context_id": context_id,
+ "language": language,
+ "env_vars": envs,
+ },
+ headers=headers,
+ timeout=(request_timeout, timeout, request_timeout, request_timeout),
+ ) as response:
+ err = extract_exception(response)
+ if err:
+ raise err
+
+ execution = Execution()
+
+ for line in response.iter_lines():
+ parse_output(
+ execution,
+ line,
+ on_stdout=on_stdout,
+ on_stderr=on_stderr,
+ on_result=on_result,
+ on_error=on_error,
+ )
+
+ return execution
+ except httpx.ReadTimeout:
+ raise format_execution_timeout_error()
+ except httpx.TimeoutException:
+ raise format_request_timeout_error()
+
+ def create_code_context(
+ self,
+ cwd: Optional[str] = None,
+ language: Optional[RunCodeLanguage] = None,
+ request_timeout: Optional[float] = None,
+ ) -> Context:
+ """
+ Creates a new context to run code in.
+
+ :param cwd: Set the current working directory for the context, defaults to `/home/user`
+ :param language: Language of the context. If not specified, defaults to Python
+ :param request_timeout: Timeout for the request in **milliseconds**
+
+ :return: Context object
+ """
+ logger.debug(f"Creating new {language} context")
+
+ data = {}
+ if language:
+ data["language"] = language
+ if cwd:
+ data["cwd"] = cwd
+
+ try:
+ headers: Dict[str, str] = {"Content-Type": "application/json"}
+ if self._envd_access_token:
+ headers["X-Access-Token"] = self._envd_access_token
+ if self.traffic_access_token:
+ headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
+
+ response = self._client.post(
+ f"{self._jupyter_url}/contexts",
+ json=data,
+ headers=headers,
+ timeout=request_timeout or self.connection_config.request_timeout,
+ )
+
+ err = extract_exception(response)
+ if err:
+ raise err
+
+ data = response.json()
+ return Context.from_json(data)
+ except httpx.TimeoutException:
+ raise format_request_timeout_error()
+
+ def remove_code_context(
+ self,
+ context: Union[Context, str],
+ ) -> None:
+ """
+ Removes a context.
+
+ :param context: Context to remove. Can be a Context object or a context ID string.
+
+ :return: None
+ """
+ context_id = context.id if isinstance(context, Context) else context
+
+ try:
+ headers: Dict[str, str] = {"Content-Type": "application/json"}
+ if self._envd_access_token:
+ headers["X-Access-Token"] = self._envd_access_token
+ if self.traffic_access_token:
+ headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
+
+ response = self._client.delete(
+ f"{self._jupyter_url}/contexts/{context_id}",
+ headers=headers,
+ timeout=self.connection_config.request_timeout,
+ )
+
+ err = extract_exception(response)
+ if err:
+ raise err
+ except httpx.TimeoutException:
+ raise format_request_timeout_error()
+
+ def list_code_contexts(self) -> List[Context]:
+ """
+ List all contexts.
+
+ :return: List of contexts.
+ """
+ try:
+ headers: Dict[str, str] = {"Content-Type": "application/json"}
+ if self._envd_access_token:
+ headers["X-Access-Token"] = self._envd_access_token
+ if self.traffic_access_token:
+ headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
+
+ response = self._client.get(
+ f"{self._jupyter_url}/contexts",
+ headers=headers,
+ timeout=self.connection_config.request_timeout,
+ )
+
+ err = extract_exception(response)
+ if err:
+ raise err
+
+ data = response.json()
+ return [Context.from_json(context_data) for context_data in data]
+ except httpx.TimeoutException:
+ raise format_request_timeout_error()
+
+ def restart_code_context(
+ self,
+ context: Union[Context, str],
+ ) -> None:
+ """
+ Restart a context.
+
+ :param context: Context to restart. Can be a Context object or a context ID string.
+
+ :return: None
+ """
+ context_id = context.id if isinstance(context, Context) else context
+
+ try:
+ headers: Dict[str, str] = {"Content-Type": "application/json"}
+ if self._envd_access_token:
+ headers["X-Access-Token"] = self._envd_access_token
+ if self.traffic_access_token:
+ headers["E2B-Traffic-Access-Token"] = self.traffic_access_token
+
+ response = self._client.post(
+ f"{self._jupyter_url}/contexts/{context_id}/restart",
+ headers=headers,
+ timeout=self.connection_config.request_timeout,
+ )
+
+ err = extract_exception(response)
+ if err:
+ raise err
+ except httpx.TimeoutException:
+ raise format_request_timeout_error()
diff --git a/python/e2b_code_interpreter/constants.py b/python/e2b_code_interpreter/constants.py
new file mode 100644
index 00000000..25d0ad73
--- /dev/null
+++ b/python/e2b_code_interpreter/constants.py
@@ -0,0 +1,3 @@
+DEFAULT_TEMPLATE = "code-interpreter-v1"
+JUPYTER_PORT = 49999
+DEFAULT_TIMEOUT = 300
diff --git a/python/e2b_code_interpreter/exceptions.py b/python/e2b_code_interpreter/exceptions.py
new file mode 100644
index 00000000..61896921
--- /dev/null
+++ b/python/e2b_code_interpreter/exceptions.py
@@ -0,0 +1,13 @@
+from e2b import TimeoutException
+
+
+def format_request_timeout_error() -> Exception:
+ return TimeoutException(
+ "Request timed out — the 'request_timeout' option can be used to increase this timeout",
+ )
+
+
+def format_execution_timeout_error() -> Exception:
+ return TimeoutException(
+ "Execution timed out — the 'timeout' option can be used to increase this timeout",
+ )
diff --git a/python/e2b_code_interpreter/main.py b/python/e2b_code_interpreter/main.py
deleted file mode 100644
index 388761a4..00000000
--- a/python/e2b_code_interpreter/main.py
+++ /dev/null
@@ -1,290 +0,0 @@
-from __future__ import annotations
-
-import logging
-import threading
-import requests
-
-from concurrent.futures import Future
-from typing import Any, Callable, List, Optional, Dict
-
-from e2b import EnvVars, ProcessMessage, Sandbox
-from e2b.constants import TIMEOUT
-
-from e2b_code_interpreter.messaging import JupyterKernelWebSocket
-from e2b_code_interpreter.models import KernelException, Execution, Result
-
-logger = logging.getLogger(__name__)
-
-
-class CodeInterpreter(Sandbox):
- """
- E2B code interpreter sandbox extension.
- """
-
- template = "code-interpreter-stateful"
-
- def __init__(
- self,
- template: Optional[str] = None,
- api_key: Optional[str] = None,
- cwd: Optional[str] = None,
- env_vars: Optional[EnvVars] = None,
- timeout: Optional[float] = TIMEOUT,
- on_stdout: Optional[Callable[[ProcessMessage], Any]] = None,
- on_stderr: Optional[Callable[[ProcessMessage], Any]] = None,
- on_exit: Optional[Callable[[int], Any]] = None,
- **kwargs,
- ):
- super().__init__(
- template=template or self.template,
- api_key=api_key,
- cwd=cwd,
- env_vars=env_vars,
- timeout=timeout,
- on_stdout=on_stdout,
- on_stderr=on_stderr,
- on_exit=on_exit,
- **kwargs,
- )
- self.notebook = JupyterExtension(self, timeout=timeout)
- # Close all the websocket connections when the interpreter is closed
- self._process_cleanup.append(self.notebook.close)
-
-
-class JupyterExtension:
- _default_kernel_id: Optional[str] = None
- _connected_kernels: Dict[str, Future[JupyterKernelWebSocket]] = {}
-
- def __init__(self, sandbox: CodeInterpreter, timeout: Optional[float] = TIMEOUT):
- self._sandbox = sandbox
- self._kernel_id_set = Future()
- self._start_connecting_to_default_kernel(timeout=timeout)
-
- def exec_cell(
- self,
- code: str,
- kernel_id: Optional[str] = None,
- on_stdout: Optional[Callable[[ProcessMessage], Any]] = None,
- on_stderr: Optional[Callable[[ProcessMessage], Any]] = None,
- on_result: Optional[Callable[[Result], Any]] = None,
- timeout: Optional[float] = TIMEOUT,
- ) -> Execution:
- """
- Execute code in a notebook cell.
-
- :param code: Code to execute
- :param kernel_id: The ID of the kernel to execute the code on. If not provided, the default kernel is used.
- :param on_stdout: A callback function to handle standard output messages from the code execution.
- :param on_stderr: A callback function to handle standard error messages from the code execution.
- :param on_result: A callback function to handle the result and display calls of the code execution.
- :param timeout: Timeout for the call
-
- :return: Result of the execution
- """
- kernel_id = kernel_id or self.default_kernel_id
- ws_future = self._connected_kernels.get(kernel_id)
-
- logger.debug(f"Executing code in kernel {kernel_id}")
-
- if ws_future:
- logger.debug(f"Using existing websocket connection to kernel {kernel_id}")
- ws = ws_future.result(timeout=timeout)
- else:
- logger.debug(f"Creating new websocket connection to kernel {kernel_id}")
- ws = self._connect_to_kernel_ws(kernel_id, timeout=timeout)
-
- session_id = ws.send_execution_message(code, on_stdout, on_stderr, on_result)
- logger.debug(
- f"Sent execution message to kernel {kernel_id}, session_id: {session_id}"
- )
-
- result = ws.get_result(session_id, timeout=timeout)
- logger.debug(
- f"Received result from kernel {kernel_id}, session_id: {session_id}, result: {result}"
- )
-
- return result
-
- @property
- def default_kernel_id(self) -> str:
- """
- Get the default kernel id
-
- :return: Default kernel id
- """
- if not self._default_kernel_id:
- logger.debug("Waiting for default kernel id")
- self._default_kernel_id = self._kernel_id_set.result()
-
- return self._default_kernel_id
-
- def create_kernel(
- self,
- cwd: str = "/home/user",
- kernel_name: Optional[str] = None,
- timeout: Optional[float] = TIMEOUT,
- ) -> str:
- """
- Creates a new kernel, this can be useful if you want to have multiple independent code execution environments.
-
- The kernel can be optionally configured to start in a specific working directory and/or
- with a specific kernel name. If no kernel name is provided, the default kernel will be used.
- Once the kernel is created, this method establishes a WebSocket connection to the new kernel for
- real-time communication.
-
- :param cwd: Sets the current working directory for the kernel. Defaults to "/home/user".
- :param kernel_name:
- Specifies which kernel should be used, useful if you have multiple kernel types.
- If not provided, the default kernel will be used.
- :param timeout: Timeout for the kernel creation request.
- :return: Kernel id of the created kernel
- """
- data = {"cwd": cwd}
- if kernel_name:
- data["kernel_name"] = kernel_name
- logger.debug(f"Creating kernel with data: {data}")
-
- response = requests.post(
- f"{self._sandbox.get_protocol()}://{self._sandbox.get_hostname(8888)}/api/kernels",
- json=data,
- timeout=timeout,
- )
- if not response.ok:
- raise KernelException(f"Failed to create kernel: {response.text}")
-
- kernel_id = response.json()["id"]
- logger.debug(f"Created kernel {kernel_id}")
-
- threading.Thread(
- target=self._connect_to_kernel_ws, args=(kernel_id, timeout)
- ).start()
- return kernel_id
-
- def restart_kernel(
- self, kernel_id: Optional[str] = None, timeout: Optional[float] = TIMEOUT
- ) -> None:
- """
- Restarts an existing Jupyter kernel. This can be useful to reset the kernel's state or to recover from errors.
-
- :param kernel_id: The unique identifier of the kernel to restart. If not provided, the default kernel is restarted.
- :param timeout: The timeout in milliseconds for the kernel restart request.
- """
- kernel_id = kernel_id or self.default_kernel_id
- logger.debug(f"Restarting kernel {kernel_id}")
-
- self._connected_kernels[kernel_id].result().close()
- del self._connected_kernels[kernel_id]
- logger.debug(f"Closed websocket connection to kernel {kernel_id}")
-
- response = requests.post(
- f"{self._sandbox.get_protocol()}://{self._sandbox.get_hostname(8888)}/api/kernels/{kernel_id}/restart",
- timeout=timeout,
- )
- if not response.ok:
- raise KernelException(f"Failed to restart kernel {kernel_id}")
-
- logger.debug(f"Restarted kernel {kernel_id}")
-
- threading.Thread(
- target=self._connect_to_kernel_ws, args=(kernel_id, timeout)
- ).start()
-
- def shutdown_kernel(
- self, kernel_id: Optional[str] = None, timeout: Optional[float] = TIMEOUT
- ) -> None:
- """
- Shuts down an existing Jupyter kernel. This method is used to gracefully terminate a kernel's process.
-
- :param kernel_id: The unique identifier of the kernel to shutdown. If not provided, the default kernel is shutdown.
- :param timeout: The timeout for the kernel shutdown request.
- """
- kernel_id = kernel_id or self.default_kernel_id
- logger.debug(f"Shutting down kernel {kernel_id}")
-
- self._connected_kernels[kernel_id].result().close()
- del self._connected_kernels[kernel_id]
- logger.debug(f"Closed websocket connection to kernel {kernel_id}")
-
- response = requests.delete(
- f"{self._sandbox.get_protocol()}://{self._sandbox.get_hostname(8888)}/api/kernels/{kernel_id}",
- timeout=timeout,
- )
- if not response.ok:
- raise KernelException(f"Failed to shutdown kernel {kernel_id}")
-
- logger.debug(f"Shutdown kernel {kernel_id}")
-
- def list_kernels(self, timeout: Optional[float] = TIMEOUT) -> List[str]:
- """
- Lists all available Jupyter kernels.
-
- This method fetches a list of all currently available Jupyter kernels from the server. It can be used
- to retrieve the IDs of all kernels that are currently running or available for connection.
-
- :param timeout: The timeout for the kernel list request.
- :return: List of kernel ids
- """
- response = requests.get(
- f"{self._sandbox.get_protocol()}://{self._sandbox.get_hostname(8888)}/api/kernels",
- timeout=timeout,
- )
-
- if not response.ok:
- raise KernelException(f"Failed to list kernels: {response.text}")
-
- return [kernel["id"] for kernel in response.json()]
-
- def close(self):
- """
- Close all the websocket connections to the kernels. It doesn't shutdown the kernels.
- """
- logger.debug("Closing all websocket connections")
- for ws in self._connected_kernels.values():
- ws.result().close()
-
- def _connect_to_kernel_ws(
- self, kernel_id: str, timeout: Optional[float] = TIMEOUT
- ) -> JupyterKernelWebSocket:
- """
- Establishes a WebSocket connection to a specified Jupyter kernel.
-
- :param kernel_id: Kernel id
- :param timeout: The timeout for the kernel connection request.
-
- :return: Websocket connection
- """
- logger.debug(f"Connecting to kernel's ({kernel_id}) websocket")
- future = Future()
- self._connected_kernels[kernel_id] = future
-
- ws = JupyterKernelWebSocket(
- url=f"{self._sandbox.get_protocol('ws')}://{self._sandbox.get_hostname(8888)}/api/kernels/{kernel_id}/channels",
- )
- ws.connect(timeout=timeout)
- logger.debug(f"Connected to kernel's ({kernel_id}) websocket.")
-
- future.set_result(ws)
- return ws
-
- def _start_connecting_to_default_kernel(
- self, timeout: Optional[float] = TIMEOUT
- ) -> None:
- """
- Start connecting to the default kernel in a separate thread to avoid blocking the main thread.
- :param timeout: Timeout for the call
- """
- logger.debug("Starting to connect to the default kernel")
-
- def setup_default_kernel():
- kernel_id = self._sandbox.filesystem.read(
- "/root/.jupyter/kernel_id", timeout=timeout
- )
- if kernel_id is None and not self._sandbox.is_open:
- return
-
- kernel_id = kernel_id.strip()
- logger.debug(f"Default kernel id: {kernel_id}")
- self._connect_to_kernel_ws(kernel_id, timeout=timeout)
- self._kernel_id_set.set_result(kernel_id)
-
- threading.Thread(target=setup_default_kernel).start()
diff --git a/python/e2b_code_interpreter/messaging.py b/python/e2b_code_interpreter/messaging.py
deleted file mode 100644
index 7f0861d1..00000000
--- a/python/e2b_code_interpreter/messaging.py
+++ /dev/null
@@ -1,258 +0,0 @@
-import json
-import logging
-import threading
-import time
-import uuid
-from concurrent.futures import Future
-from queue import Queue
-from typing import Callable, Dict, List, Any, Optional
-
-from e2b import ProcessMessage
-from e2b.constants import TIMEOUT
-from e2b.sandbox import TimeoutException
-from e2b.sandbox.websocket_client import WebSocket
-from e2b.utils.future import DeferredFuture
-from pydantic import ConfigDict, PrivateAttr, BaseModel
-
-from e2b_code_interpreter.models import Execution, Result, Error
-
-logger = logging.getLogger(__name__)
-
-
-class CellExecution:
- """
- Represents the execution of a cell in the Jupyter kernel.
- It's an internal class used by JupyterKernelWebSocket.
- """
-
- input_accepted: bool = False
- on_stdout: Optional[Callable[[ProcessMessage], Any]] = None
- on_stderr: Optional[Callable[[ProcessMessage], Any]] = None
- on_result: Optional[Callable[[Result], Any]] = None
-
- def __init__(
- self,
- on_stdout: Optional[Callable[[ProcessMessage], Any]] = None,
- on_stderr: Optional[Callable[[ProcessMessage], Any]] = None,
- on_result: Optional[Callable[[Result], Any]] = None,
- ):
- self.partial_result = Execution()
- self.execution = Future()
- self.on_stdout = on_stdout
- self.on_stderr = on_stderr
- self.on_result = on_result
-
-
-class JupyterKernelWebSocket(BaseModel):
- model_config = ConfigDict(arbitrary_types_allowed=True)
-
- url: str
-
- _cells: Dict[str, CellExecution] = {}
- _waiting_for_replies: Dict[str, DeferredFuture] = PrivateAttr(default_factory=dict)
- _queue_in: Queue = PrivateAttr(default_factory=Queue)
- _queue_out: Queue = PrivateAttr(default_factory=Queue)
- _process_cleanup: List[Callable[[], Any]] = PrivateAttr(default_factory=list)
- _closed: bool = PrivateAttr(default=False)
-
- def process_messages(self):
- while True:
- data = self._queue_out.get()
-
- logger.debug(f"WebSocket received message: {data}".strip())
- self._receive_message(json.loads(data))
- self._queue_out.task_done()
-
- def connect(self, timeout: float = TIMEOUT):
- started = threading.Event()
- stopped = threading.Event()
- self._process_cleanup.append(stopped.set)
-
- threading.Thread(
- target=self.process_messages, daemon=True, name="e2b-process-messages"
- ).start()
-
- threading.Thread(
- target=WebSocket(
- url=self.url,
- queue_in=self._queue_in,
- queue_out=self._queue_out,
- started=started,
- stopped=stopped,
- ).run,
- daemon=True,
- name="e2b-code-interpreter-websocket",
- ).start()
-
- logger.debug("WebSocket waiting to start")
-
- try:
- start_time = time.time()
- while (
- not started.is_set()
- and time.time() - start_time < timeout
- and not self._closed
- ):
- time.sleep(0.1)
-
- if not started.is_set():
- raise TimeoutException("WebSocket failed to start")
- except BaseException as e:
- self.close()
- raise Exception(f"WebSocket failed to start: {e}") from e
-
- logger.debug("WebSocket started")
-
- @staticmethod
- def _get_execute_request(msg_id: str, code: str) -> str:
- return json.dumps(
- {
- "header": {
- "msg_id": msg_id,
- "username": "e2b",
- "session": str(uuid.uuid4()),
- "msg_type": "execute_request",
- "version": "5.3",
- },
- "parent_header": {},
- "metadata": {},
- "content": {
- "code": code,
- "silent": False,
- "store_history": False,
- "user_expressions": {},
- "allow_stdin": False,
- },
- }
- )
-
- def send_execution_message(
- self,
- code: str,
- on_stdout: Optional[Callable[[ProcessMessage], Any]] = None,
- on_stderr: Optional[Callable[[ProcessMessage], Any]] = None,
- on_result: Optional[Callable[[Result], Any]] = None,
- ) -> str:
- message_id = str(uuid.uuid4())
- logger.debug(f"Sending execution message: {message_id}")
-
- self._cells[message_id] = CellExecution(
- on_stdout=on_stdout,
- on_stderr=on_stderr,
- on_result=on_result,
- )
- request = self._get_execute_request(message_id, code)
- self._queue_in.put(request)
- return message_id
-
- def get_result(
- self, message_id: str, timeout: Optional[float] = TIMEOUT
- ) -> Execution:
- result = self._cells[message_id].execution.result(timeout=timeout)
- logger.debug(f"Got result for message: {message_id}")
- del self._cells[message_id]
- return result
-
- def _receive_message(self, data: dict):
- """
- Process messages from the WebSocket
-
- Message types:
- https://jupyter-client.readthedocs.io/en/stable/messaging.html
-
- :param data: The message data
- """
- parent_msg_ig = data["parent_header"]["msg_id"]
- logger.debug(f"Received message {data['msg_type']} for {parent_msg_ig}")
-
- cell = self._cells.get(parent_msg_ig)
- if not cell:
- return
-
- execution = cell.partial_result
-
- if data["msg_type"] == "error":
- logger.debug(f"Cell {parent_msg_ig} finished execution with error")
- execution.error = Error(
- name=data["content"]["ename"],
- value=data["content"]["evalue"],
- traceback_raw=data["content"]["traceback"],
- )
-
- elif data["msg_type"] == "stream":
- if data["content"]["name"] == "stdout":
- execution.logs.stdout.append(data["content"]["text"])
- if cell.on_stdout:
- cell.on_stdout(
- ProcessMessage(
- line=data["content"]["text"],
- timestamp=time.time_ns(),
- )
- )
-
- elif data["content"]["name"] == "stderr":
- execution.logs.stderr.append(data["content"]["text"])
- if cell.on_stderr:
- cell.on_stderr(
- ProcessMessage(
- line=data["content"]["text"],
- error=True,
- timestamp=time.time_ns(),
- )
- )
-
- elif data["msg_type"] in "display_data":
- result = Result(is_main_result=False, data=data["content"]["data"])
- execution.results.append(result)
- if cell.on_result:
- cell.on_result(result)
- elif data["msg_type"] == "execute_result":
- result = Result(is_main_result=True, data=data["content"]["data"])
- execution.results.append(result)
- if cell.on_result:
- cell.on_result(result)
- elif data["msg_type"] == "status":
- if data["content"]["execution_state"] == "idle":
- if cell.input_accepted:
- logger.debug(f"Cell {parent_msg_ig} finished execution")
- cell.execution.set_result(execution)
-
- elif data["content"]["execution_state"] == "error":
- logger.debug(f"Cell {parent_msg_ig} finished execution with error")
- execution.error = Error(
- name=data["content"]["ename"],
- value=data["content"]["evalue"],
- traceback_raw=data["content"]["traceback"],
- )
- cell.execution.set_result(execution)
-
- elif data["msg_type"] == "execute_reply":
- if data["content"]["status"] == "error":
- logger.debug(f"Cell {parent_msg_ig} finished execution with error")
- execution.error = Error(
- name=data["content"]["ename"],
- value=data["content"]["evalue"],
- traceback_raw=data["content"]["traceback"],
- )
- elif data["content"]["status"] == "ok":
- pass
-
- elif data["msg_type"] == "execute_input":
- logger.debug(f"Input accepted for {parent_msg_ig}")
- cell.input_accepted = True
- else:
- logger.warning(f"[UNHANDLED MESSAGE TYPE]: {data['msg_type']}")
-
- def close(self):
- logger.debug("Closing WebSocket")
- self._closed = True
-
- for cancel in self._process_cleanup:
- cancel()
-
- self._process_cleanup.clear()
-
- for handler in self._waiting_for_replies.values():
- logger.debug(f"Cancelling waiting for execution result for {handler}")
- handler.cancel()
- del handler
diff --git a/python/e2b_code_interpreter/models.py b/python/e2b_code_interpreter/models.py
index b9953eba..ff691b54 100644
--- a/python/e2b_code_interpreter/models.py
+++ b/python/e2b_code_interpreter/models.py
@@ -1,29 +1,96 @@
-import copy
-from typing import List, Optional, Iterable, Dict
-from pydantic import BaseModel, field_serializer
+import inspect
+import json
+import logging
+
+from e2b import NotFoundException, TimeoutException, SandboxException
+from dataclasses import dataclass, field
+from typing import (
+ List,
+ Literal,
+ Optional,
+ Iterable,
+ Dict,
+ TypeVar,
+ Callable,
+ Awaitable,
+ Any,
+ Union,
+)
+
+from httpx import Response
+
+from .charts import Chart, _deserialize_chart
+
+RunCodeLanguage = Union[
+ Literal["python", "javascript", "typescript", "r", "java", "bash"],
+ str,
+]
+
+T = TypeVar("T")
+OutputHandler = Union[Callable[[T], Any],]
+
+OutputHandlerWithAsync = Union[
+ OutputHandler[T],
+ Callable[[T], Awaitable[Any]],
+]
+
+logger = logging.getLogger(__name__)
+
+
+@dataclass
+class OutputMessage:
+ """
+ Represents an output message from the sandbox code execution.
+ """
+
+ line: str
+ """
+ The output line.
+ """
+ timestamp: int
+ """
+ Unix epoch in nanoseconds
+ """
+ error: bool = False
+ """
+ Whether the output is an error.
+ """
+ def __str__(self):
+ return self.line
-class Error(BaseModel):
+
+@dataclass
+class ExecutionError:
"""
Represents an error that occurred during the execution of a cell.
The error contains the name of the error, the value of the error, and the traceback.
"""
name: str
- "Name of the exception."
+ """
+ Name of the error.
+ """
value: str
- "Value of the exception."
- traceback_raw: List[str]
- "List of strings representing the traceback."
+ """
+ Value of the error.
+ """
+ traceback: str
+ """
+ The raw traceback of the error.
+ """
- @property
- def traceback(self) -> str:
- """
- Returns the traceback as a single string.
+ def __init__(self, name: str, value: str, traceback: str, **kwargs):
+ self.name = name
+ self.value = value
+ self.traceback = traceback
- :return: The traceback as a single string.
+ def to_json(self) -> str:
+ """
+ Returns the JSON representation of the Error object.
"""
- return "\n".join(self.traceback_raw)
+ data = {"name": self.name, "value": self.value, "traceback": self.traceback}
+ return json.dumps(data)
class MIMEType(str):
@@ -32,6 +99,7 @@ class MIMEType(str):
"""
+@dataclass
class Result:
"""
Represents the data to be displayed as a result of executing a cell in a Jupyter notebook.
@@ -40,10 +108,11 @@ class Result:
The result can contain multiple types of data, such as text, images, plots, etc. Each type of data is represented
as a string, and the result can contain multiple types of data. The display calls don't have to have text representation,
for the actual result the representation is always present for the result, the other representations are always optional.
-
- The class also provides methods to display the data in a Jupyter notebook.
"""
+ def __getitem__(self, item):
+ return getattr(self, item)
+
text: Optional[str] = None
html: Optional[str] = None
markdown: Optional[str] = None
@@ -54,36 +123,51 @@ class Result:
latex: Optional[str] = None
json: Optional[dict] = None
javascript: Optional[str] = None
+ data: Optional[dict] = None
+ chart: Optional[Chart] = None
+ is_main_result: bool = False
+ """Whether this data is the result of the cell. Data can be produced by display calls of which can be multiple in a cell."""
extra: Optional[dict] = None
- "Extra data that can be included. Not part of the standard types."
-
- is_main_result: bool
- "Whether this data is the result of the cell. Data can be produced by display calls of which can be multiple in a cell."
-
- raw: Dict[MIMEType, str]
- "Dictionary that maps MIME types to their corresponding string representations of the data."
-
- def __init__(self, is_main_result: bool, data: [MIMEType, str]):
+ """Extra data that can be included. Not part of the standard types."""
+
+ def __init__(
+ self,
+ text: Optional[str] = None,
+ html: Optional[str] = None,
+ markdown: Optional[str] = None,
+ svg: Optional[str] = None,
+ png: Optional[str] = None,
+ jpeg: Optional[str] = None,
+ pdf: Optional[str] = None,
+ latex: Optional[str] = None,
+ json: Optional[dict] = None,
+ javascript: Optional[str] = None,
+ data: Optional[dict] = None,
+ chart: Optional[dict] = None,
+ is_main_result: bool = False,
+ extra: Optional[dict] = None,
+ **kwargs, # Allows for future expansion
+ ):
+ self.text = text
+ self.html = html
+ self.markdown = markdown
+ self.svg = svg
+ self.png = png
+ self.jpeg = jpeg
+ self.pdf = pdf
+ self.latex = latex
+ self.json = json
+ self.javascript = javascript
+ self.data = data
+ if chart:
+ try:
+ self.chart = _deserialize_chart(chart)
+ except Exception as e:
+ logger.error(
+ f"Error deserializing chart, check if you are using the latest version of the library: {e}"
+ )
self.is_main_result = is_main_result
- self.raw = copy.deepcopy(data)
-
- self.text = data.pop("text/plain", None)
- self.html = data.pop("text/html", None)
- self.markdown = data.pop("text/markdown", None)
- self.svg = data.pop("image/svg+xml", None)
- self.png = data.pop("image/png", None)
- self.jpeg = data.pop("image/jpeg", None)
- self.pdf = data.pop("application/pdf", None)
- self.latex = data.pop("text/latex", None)
- self.json = data.pop("application/json", None)
- self.javascript = data.pop("application/javascript", None)
- self.extra = data
-
- # Allows to iterate over formats()
- def __getitem__(self, item):
- if item in self.raw:
- return self.raw[item]
- return getattr(self, item)
+ self.extra = extra
def formats(self) -> Iterable[str]:
"""
@@ -92,6 +176,8 @@ def formats(self) -> Iterable[str]:
:return: All available formats of the result in MIME types.
"""
formats = []
+ if self.text:
+ formats.append("text")
if self.html:
formats.append("html")
if self.markdown:
@@ -110,9 +196,14 @@ def formats(self) -> Iterable[str]:
formats.append("json")
if self.javascript:
formats.append("javascript")
+ if self.data:
+ formats.append("data")
+ if self.chart:
+ formats.append("chart")
- for key in self.extra:
- formats.append(key)
+ if self.extra:
+ for key in self.extra:
+ formats.append(key)
return formats
@@ -122,7 +213,13 @@ def __str__(self) -> Optional[str]:
:return: The text representation of the data.
"""
- return self.text
+ return self.__repr__()
+
+ def __repr__(self) -> str:
+ if self.text:
+ return f"Result({self.text})"
+ else:
+ return "Result(Formats: " + ", ".join(self.formats()) + ")"
def _repr_html_(self) -> Optional[str]:
"""
@@ -197,31 +294,81 @@ def _repr_javascript_(self) -> Optional[str]:
return self.javascript
-class Logs(BaseModel):
+@dataclass(repr=False)
+class Logs:
"""
Data printed to stdout and stderr during execution, usually by print statements, logs, warnings, subprocesses, etc.
"""
- stdout: List[str] = []
- "List of strings printed to stdout by prints, subprocesses, etc."
- stderr: List[str] = []
- "List of strings printed to stderr by prints, subprocesses, etc."
+ stdout: List[str] = field(default_factory=list)
+ """List of strings printed to stdout by prints, subprocesses, etc."""
+ stderr: List[str] = field(default_factory=list)
+ """List of strings printed to stderr by prints, subprocesses, etc."""
+
+ def __init__(self, stdout: List[str] = None, stderr: List[str] = None, **kwargs):
+ self.stdout = stdout or []
+ self.stderr = stderr or []
+ def __repr__(self):
+ return f"Logs(stdout: {self.stdout}, stderr: {self.stderr})"
-class Execution(BaseModel):
+ def to_json(self) -> str:
+ """
+ Returns the JSON representation of the Logs object.
+ """
+ data = {"stdout": self.stdout, "stderr": self.stderr}
+ return json.dumps(data)
+
+
+def serialize_results(results: List[Result]) -> List[Dict[str, str]]:
"""
- Represents the result of a cell execution.
+ Serializes the results to JSON.
"""
+ serialized = []
+ for result in results:
+ serialized_dict = {}
+ for key in result.formats():
+ if key == "chart":
+ serialized_dict[key] = result.chart.to_dict()
+ else:
+ serialized_dict[key] = result[key]
+
+ serialized_dict["text"] = result.text
+ serialized.append(serialized_dict)
+
+ return serialized
+
- class Config:
- arbitrary_types_allowed = True
+@dataclass(repr=False)
+class Execution:
+ """
+ Represents the result of a cell execution.
+ """
- results: List[Result] = []
- "List of the result of the cell (interactively interpreted last line), display calls (e.g. matplotlib plots)."
- logs: Logs = Logs()
- "Logs printed to stdout and stderr during execution."
- error: Optional[Error] = None
- "Error object if an error occurred, None otherwise."
+ results: List[Result] = field(default_factory=list)
+ """List of the result of the cell (interactively interpreted last line), display calls (e.g. matplotlib plots)."""
+ logs: Logs = field(default_factory=Logs)
+ """Logs printed to stdout and stderr during execution."""
+ error: Optional[ExecutionError] = None
+ """Error object if an error occurred, None otherwise."""
+ execution_count: Optional[int] = None
+ """Execution count of the cell."""
+
+ def __init__(
+ self,
+ results: List[Result] = None,
+ logs: Logs = None,
+ error: Optional[ExecutionError] = None,
+ execution_count: Optional[int] = None,
+ **kwargs,
+ ):
+ self.results = results or []
+ self.logs = logs or Logs()
+ self.error = error
+ self.execution_count = execution_count
+
+ def __repr__(self):
+ return f"Execution(Results: {self.results}, Logs: {self.logs}, Error: {self.error})"
@property
def text(self) -> Optional[str]:
@@ -238,25 +385,132 @@ def to_json(self) -> str:
"""
Returns the JSON representation of the Execution object.
"""
- return self.model_dump_json(exclude_none=True)
-
- @field_serializer("results", when_used="json")
- def serialize_results(results: List[Result]) -> List[Dict[str, str]]:
- """
- Serializes the results to JSON.
- This method is used by the Pydantic JSON encoder.
- """
- serialized = []
- for result in results:
- serialized_dict = {key: result[key] for key in result.formats()}
- serialized_dict['text'] = result.text
- serialized.append(serialized_dict)
- return serialized
-
+ data = {
+ "results": serialize_results(self.results),
+ "logs": self.logs.to_json(),
+ "error": self.error.to_json() if self.error else None,
+ }
+ return json.dumps(data)
+
+
+async def aextract_exception(res: Response):
+ if res.is_success:
+ return None
+
+ await res.aread()
+ return extract_exception(res)
+
+
+def extract_exception(res: Response):
+ if res.is_success:
+ return None
+
+ res.read()
+ return format_exception(res)
+
+
+def format_exception(res: Response):
+ if res.is_success:
+ return None
+
+ if res.status_code == 404:
+ return NotFoundException(res.text)
+ elif res.status_code == 502:
+ return TimeoutException(
+ f"{res.text}: This error is likely due to sandbox timeout. You can modify the sandbox timeout by passing 'timeout' when starting the sandbox or calling '.set_timeout' on the sandbox with the desired timeout."
+ )
+ else:
+ return SandboxException(f"{res.status_code}: {res.text}")
+
+
+def parse_output(
+ execution: Execution,
+ output: str,
+ on_stdout: Optional[OutputHandler[OutputMessage]] = None,
+ on_stderr: Optional[OutputHandler[OutputMessage]] = None,
+ on_result: Optional[OutputHandler[Result]] = None,
+ on_error: Optional[OutputHandler[ExecutionError]] = None,
+):
+ _parse_output(execution, output, on_stdout, on_stderr, on_result, on_error)
+
+
+async def async_parse_output(
+ execution: Execution,
+ output: str,
+ on_stdout: Optional[OutputHandlerWithAsync[OutputMessage]] = None,
+ on_stderr: Optional[OutputHandlerWithAsync[OutputMessage]] = None,
+ on_result: Optional[OutputHandlerWithAsync[Result]] = None,
+ on_error: Optional[OutputHandlerWithAsync[ExecutionError]] = None,
+):
+ none_or_awaitable = _parse_output(
+ execution, output, on_stdout, on_stderr, on_result, on_error
+ )
+ if inspect.isawaitable(none_or_awaitable):
+ await none_or_awaitable
+
+
+def _parse_output(
+ execution: Execution,
+ output: str,
+ on_stdout: Optional[OutputHandler[OutputMessage]] = None,
+ on_stderr: Optional[OutputHandler[OutputMessage]] = None,
+ on_result: Optional[OutputHandler[Result]] = None,
+ on_error: Optional[OutputHandler[ExecutionError]] = None,
+) -> Union[None, Awaitable[Any]]:
+ data = json.loads(output)
+ data_type = data.pop("type")
+
+ if data_type == "result":
+ result = Result(**data)
+ execution.results.append(result)
+ if on_result:
+ return on_result(result)
+ elif data_type == "stdout":
+ execution.logs.stdout.append(data["text"])
+ if on_stdout:
+ return on_stdout(OutputMessage(data["text"], data["timestamp"], False))
+ elif data_type == "stderr":
+ execution.logs.stderr.append(data["text"])
+ if on_stderr:
+ return on_stderr(OutputMessage(data["text"], data["timestamp"], True))
+ elif data_type == "error":
+ execution.error = ExecutionError(data["name"], data["value"], data["traceback"])
+ if on_error:
+ return on_error(execution.error)
+ elif data_type == "number_of_executions":
+ execution.execution_count = data["execution_count"]
+
+ return None
+
+
+@dataclass
+class Context:
+ """
+ Represents a context for code execution.
+ """
-class KernelException(Exception):
+ id: str
+ """
+ The ID of the context.
+ """
+ language: str
+ """
+ The language of the context.
+ """
+ cwd: str
"""
- Exception raised when a kernel operation fails.
+ The working directory of the context.
"""
- pass
+ def __init__(self, context_id: str, language: str, cwd: str, **kwargs):
+ self.id = context_id
+ self.language = language
+ self.cwd = cwd
+
+ @classmethod
+ def from_json(cls, data: Dict[str, str]):
+ return cls(
+ context_id=data.get("id"),
+ language=data.get("language"),
+ cwd=data.get("cwd"),
+ )
diff --git a/python/example.py b/python/example.py
index bd31bdd4..56b447bf 100644
--- a/python/example.py
+++ b/python/example.py
@@ -1,6 +1,9 @@
-from e2b_code_interpreter.main import CodeInterpreter
+import asyncio
+
from dotenv import load_dotenv
+from e2b_code_interpreter import Sandbox
+
load_dotenv()
@@ -8,23 +11,32 @@
import matplotlib.pyplot as plt
import numpy as np
-x = np.linspace(0, 20, 100)
-y = np.sin(x)
+# Step 1: Define the data for the pie chart
+categories = ["No", "No, in blue"]
+sizes = [90, 10]
-plt.plot(x, y)
-plt.show()
+# Step 2: Create the figure and axis objects
+fig, ax = plt.subplots(figsize=(8, 8))
-x = np.linspace(0, 10, 100)
+plt.xlabel("x")
+plt.ylabel("y")
-plt.plot(x, y)
-plt.show()
+# Step 3: Create the pie chart
+ax.pie(sizes, labels=categories, autopct='%1.1f%%', startangle=90, colors=plt.cm.Pastel1.colors[:len(categories)])
-import pandas
-pandas.DataFrame({"a": [1, 2, 3]})
+# Step 4: Add title and legend
+ax.axis('equal') # Equal aspect ratio ensures that pie is drawn as a circle
+plt.title('Will I wake up early tomorrow?')
+
+# Step 5: Show the plot
+plt.show()
"""
-with CodeInterpreter() as sandbox:
- result = sandbox.notebook.exec_cell(code)
-print(result.result.formats())
-print(len(result.display_data))
+async def run():
+ sbx = Sandbox.create(timeout=60)
+ e = sbx.run_code(code)
+ print(e.results[0].chart)
+
+
+asyncio.run(run())
diff --git a/python/package.json b/python/package.json
index f0ab4b90..b533e8f3 100644
--- a/python/package.json
+++ b/python/package.json
@@ -1,11 +1,16 @@
{
"name": "@e2b/code-interpreter-python",
"private": true,
- "version": "0.0.5",
+ "version": "2.8.0",
+ "packageManager": "pnpm@9.15.9",
"scripts": {
- "test": "poetry run pytest -n 1 --verbose -x",
+ "test": "poetry run pytest -n 4 --verbose -x",
+ "example": "poetry run python3 example.py",
+ "async-example": "poetry run python3 async_example.py",
"postVersion": "poetry version $(pnpm pkg get version --workspaces=false | tr -d \\\")",
"postPublish": "poetry build && poetry config pypi-token.pypi ${PYPI_TOKEN} && poetry publish --skip-existing",
- "pretest": "poetry install"
+ "pretest": "poetry install",
+ "lint": "poetry run ruff check .",
+ "format": "poetry run ruff format ."
}
-}
\ No newline at end of file
+}
diff --git a/python/poetry.lock b/python/poetry.lock
index e6f38a56..8cfb8d1e 100644
--- a/python/poetry.lock
+++ b/python/poetry.lock
@@ -1,802 +1,949 @@
-# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
+# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
[[package]]
-name = "aenum"
-version = "3.1.15"
-description = "Advanced Enumerations (compatible with Python's stdlib Enum), NamedTuples, and NamedConstants"
+name = "anyio"
+version = "4.13.0"
+description = "High-level concurrency and networking framework on top of asyncio or Trio"
optional = false
-python-versions = "*"
+python-versions = ">=3.10"
files = [
- {file = "aenum-3.1.15-py2-none-any.whl", hash = "sha256:27b1710b9d084de6e2e695dab78fe9f269de924b51ae2850170ee7e1ca6288a5"},
- {file = "aenum-3.1.15-py3-none-any.whl", hash = "sha256:e0dfaeea4c2bd362144b87377e2c61d91958c5ed0b4daf89cb6f45ae23af6288"},
- {file = "aenum-3.1.15.tar.gz", hash = "sha256:8cbd76cd18c4f870ff39b24284d3ea028fbe8731a58df3aa581e434c575b9559"},
+ {file = "anyio-4.13.0-py3-none-any.whl", hash = "sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708"},
+ {file = "anyio-4.13.0.tar.gz", hash = "sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc"},
]
+[package.dependencies]
+exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""}
+idna = ">=2.8"
+typing_extensions = {version = ">=4.5", markers = "python_version < \"3.13\""}
+
+[package.extras]
+trio = ["trio (>=0.32.0)"]
+
[[package]]
-name = "aiohttp"
-version = "3.9.5"
-description = "Async http client/server framework (asyncio)"
+name = "attrs"
+version = "26.1.0"
+description = "Classes Without Boilerplate"
optional = false
-python-versions = ">=3.8"
+python-versions = ">=3.9"
files = [
- {file = "aiohttp-3.9.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fcde4c397f673fdec23e6b05ebf8d4751314fa7c24f93334bf1f1364c1c69ac7"},
- {file = "aiohttp-3.9.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5d6b3f1fabe465e819aed2c421a6743d8debbde79b6a8600739300630a01bf2c"},
- {file = "aiohttp-3.9.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ae79c1bc12c34082d92bf9422764f799aee4746fd7a392db46b7fd357d4a17a"},
- {file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d3ebb9e1316ec74277d19c5f482f98cc65a73ccd5430540d6d11682cd857430"},
- {file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84dabd95154f43a2ea80deffec9cb44d2e301e38a0c9d331cc4aa0166fe28ae3"},
- {file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c8a02fbeca6f63cb1f0475c799679057fc9268b77075ab7cf3f1c600e81dd46b"},
- {file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c26959ca7b75ff768e2776d8055bf9582a6267e24556bb7f7bd29e677932be72"},
- {file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:714d4e5231fed4ba2762ed489b4aec07b2b9953cf4ee31e9871caac895a839c0"},
- {file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7a6a8354f1b62e15d48e04350f13e726fa08b62c3d7b8401c0a1314f02e3558"},
- {file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c413016880e03e69d166efb5a1a95d40f83d5a3a648d16486592c49ffb76d0db"},
- {file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ff84aeb864e0fac81f676be9f4685f0527b660f1efdc40dcede3c251ef1e867f"},
- {file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ad7f2919d7dac062f24d6f5fe95d401597fbb015a25771f85e692d043c9d7832"},
- {file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:702e2c7c187c1a498a4e2b03155d52658fdd6fda882d3d7fbb891a5cf108bb10"},
- {file = "aiohttp-3.9.5-cp310-cp310-win32.whl", hash = "sha256:67c3119f5ddc7261d47163ed86d760ddf0e625cd6246b4ed852e82159617b5fb"},
- {file = "aiohttp-3.9.5-cp310-cp310-win_amd64.whl", hash = "sha256:471f0ef53ccedec9995287f02caf0c068732f026455f07db3f01a46e49d76bbb"},
- {file = "aiohttp-3.9.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e0ae53e33ee7476dd3d1132f932eeb39bf6125083820049d06edcdca4381f342"},
- {file = "aiohttp-3.9.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c088c4d70d21f8ca5c0b8b5403fe84a7bc8e024161febdd4ef04575ef35d474d"},
- {file = "aiohttp-3.9.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:639d0042b7670222f33b0028de6b4e2fad6451462ce7df2af8aee37dcac55424"},
- {file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f26383adb94da5e7fb388d441bf09c61e5e35f455a3217bfd790c6b6bc64b2ee"},
- {file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:66331d00fb28dc90aa606d9a54304af76b335ae204d1836f65797d6fe27f1ca2"},
- {file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ff550491f5492ab5ed3533e76b8567f4b37bd2995e780a1f46bca2024223233"},
- {file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f22eb3a6c1080d862befa0a89c380b4dafce29dc6cd56083f630073d102eb595"},
- {file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a81b1143d42b66ffc40a441379387076243ef7b51019204fd3ec36b9f69e77d6"},
- {file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f64fd07515dad67f24b6ea4a66ae2876c01031de91c93075b8093f07c0a2d93d"},
- {file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:93e22add827447d2e26d67c9ac0161756007f152fdc5210277d00a85f6c92323"},
- {file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:55b39c8684a46e56ef8c8d24faf02de4a2b2ac60d26cee93bc595651ff545de9"},
- {file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4715a9b778f4293b9f8ae7a0a7cef9829f02ff8d6277a39d7f40565c737d3771"},
- {file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:afc52b8d969eff14e069a710057d15ab9ac17cd4b6753042c407dcea0e40bf75"},
- {file = "aiohttp-3.9.5-cp311-cp311-win32.whl", hash = "sha256:b3df71da99c98534be076196791adca8819761f0bf6e08e07fd7da25127150d6"},
- {file = "aiohttp-3.9.5-cp311-cp311-win_amd64.whl", hash = "sha256:88e311d98cc0bf45b62fc46c66753a83445f5ab20038bcc1b8a1cc05666f428a"},
- {file = "aiohttp-3.9.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:c7a4b7a6cf5b6eb11e109a9755fd4fda7d57395f8c575e166d363b9fc3ec4678"},
- {file = "aiohttp-3.9.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:0a158704edf0abcac8ac371fbb54044f3270bdbc93e254a82b6c82be1ef08f3c"},
- {file = "aiohttp-3.9.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d153f652a687a8e95ad367a86a61e8d53d528b0530ef382ec5aaf533140ed00f"},
- {file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82a6a97d9771cb48ae16979c3a3a9a18b600a8505b1115cfe354dfb2054468b4"},
- {file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:60cdbd56f4cad9f69c35eaac0fbbdf1f77b0ff9456cebd4902f3dd1cf096464c"},
- {file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8676e8fd73141ded15ea586de0b7cda1542960a7b9ad89b2b06428e97125d4fa"},
- {file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da00da442a0e31f1c69d26d224e1efd3a1ca5bcbf210978a2ca7426dfcae9f58"},
- {file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18f634d540dd099c262e9f887c8bbacc959847cfe5da7a0e2e1cf3f14dbf2daf"},
- {file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:320e8618eda64e19d11bdb3bd04ccc0a816c17eaecb7e4945d01deee2a22f95f"},
- {file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:2faa61a904b83142747fc6a6d7ad8fccff898c849123030f8e75d5d967fd4a81"},
- {file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:8c64a6dc3fe5db7b1b4d2b5cb84c4f677768bdc340611eca673afb7cf416ef5a"},
- {file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:393c7aba2b55559ef7ab791c94b44f7482a07bf7640d17b341b79081f5e5cd1a"},
- {file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c671dc117c2c21a1ca10c116cfcd6e3e44da7fcde37bf83b2be485ab377b25da"},
- {file = "aiohttp-3.9.5-cp312-cp312-win32.whl", hash = "sha256:5a7ee16aab26e76add4afc45e8f8206c95d1d75540f1039b84a03c3b3800dd59"},
- {file = "aiohttp-3.9.5-cp312-cp312-win_amd64.whl", hash = "sha256:5ca51eadbd67045396bc92a4345d1790b7301c14d1848feaac1d6a6c9289e888"},
- {file = "aiohttp-3.9.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:694d828b5c41255e54bc2dddb51a9f5150b4eefa9886e38b52605a05d96566e8"},
- {file = "aiohttp-3.9.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0605cc2c0088fcaae79f01c913a38611ad09ba68ff482402d3410bf59039bfb8"},
- {file = "aiohttp-3.9.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4558e5012ee03d2638c681e156461d37b7a113fe13970d438d95d10173d25f78"},
- {file = "aiohttp-3.9.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dbc053ac75ccc63dc3a3cc547b98c7258ec35a215a92bd9f983e0aac95d3d5b"},
- {file = "aiohttp-3.9.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4109adee842b90671f1b689901b948f347325045c15f46b39797ae1bf17019de"},
- {file = "aiohttp-3.9.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6ea1a5b409a85477fd8e5ee6ad8f0e40bf2844c270955e09360418cfd09abac"},
- {file = "aiohttp-3.9.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3c2890ca8c59ee683fd09adf32321a40fe1cf164e3387799efb2acebf090c11"},
- {file = "aiohttp-3.9.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3916c8692dbd9d55c523374a3b8213e628424d19116ac4308e434dbf6d95bbdd"},
- {file = "aiohttp-3.9.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8d1964eb7617907c792ca00b341b5ec3e01ae8c280825deadbbd678447b127e1"},
- {file = "aiohttp-3.9.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d5ab8e1f6bee051a4bf6195e38a5c13e5e161cb7bad83d8854524798bd9fcd6e"},
- {file = "aiohttp-3.9.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:52c27110f3862a1afbcb2af4281fc9fdc40327fa286c4625dfee247c3ba90156"},
- {file = "aiohttp-3.9.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:7f64cbd44443e80094309875d4f9c71d0401e966d191c3d469cde4642bc2e031"},
- {file = "aiohttp-3.9.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8b4f72fbb66279624bfe83fd5eb6aea0022dad8eec62b71e7bf63ee1caadeafe"},
- {file = "aiohttp-3.9.5-cp38-cp38-win32.whl", hash = "sha256:6380c039ec52866c06d69b5c7aad5478b24ed11696f0e72f6b807cfb261453da"},
- {file = "aiohttp-3.9.5-cp38-cp38-win_amd64.whl", hash = "sha256:da22dab31d7180f8c3ac7c7635f3bcd53808f374f6aa333fe0b0b9e14b01f91a"},
- {file = "aiohttp-3.9.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1732102949ff6087589408d76cd6dea656b93c896b011ecafff418c9661dc4ed"},
- {file = "aiohttp-3.9.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c6021d296318cb6f9414b48e6a439a7f5d1f665464da507e8ff640848ee2a58a"},
- {file = "aiohttp-3.9.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:239f975589a944eeb1bad26b8b140a59a3a320067fb3cd10b75c3092405a1372"},
- {file = "aiohttp-3.9.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b7b30258348082826d274504fbc7c849959f1989d86c29bc355107accec6cfb"},
- {file = "aiohttp-3.9.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd2adf5c87ff6d8b277814a28a535b59e20bfea40a101db6b3bdca7e9926bc24"},
- {file = "aiohttp-3.9.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a3d838441bebcf5cf442700e3963f58b5c33f015341f9ea86dcd7d503c07e2"},
- {file = "aiohttp-3.9.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e3a1ae66e3d0c17cf65c08968a5ee3180c5a95920ec2731f53343fac9bad106"},
- {file = "aiohttp-3.9.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9c69e77370cce2d6df5d12b4e12bdcca60c47ba13d1cbbc8645dd005a20b738b"},
- {file = "aiohttp-3.9.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0cbf56238f4bbf49dab8c2dc2e6b1b68502b1e88d335bea59b3f5b9f4c001475"},
- {file = "aiohttp-3.9.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:d1469f228cd9ffddd396d9948b8c9cd8022b6d1bf1e40c6f25b0fb90b4f893ed"},
- {file = "aiohttp-3.9.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:45731330e754f5811c314901cebdf19dd776a44b31927fa4b4dbecab9e457b0c"},
- {file = "aiohttp-3.9.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:3fcb4046d2904378e3aeea1df51f697b0467f2aac55d232c87ba162709478c46"},
- {file = "aiohttp-3.9.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8cf142aa6c1a751fcb364158fd710b8a9be874b81889c2bd13aa8893197455e2"},
- {file = "aiohttp-3.9.5-cp39-cp39-win32.whl", hash = "sha256:7b179eea70833c8dee51ec42f3b4097bd6370892fa93f510f76762105568cf09"},
- {file = "aiohttp-3.9.5-cp39-cp39-win_amd64.whl", hash = "sha256:38d80498e2e169bc61418ff36170e0aad0cd268da8b38a17c4cf29d254a8b3f1"},
- {file = "aiohttp-3.9.5.tar.gz", hash = "sha256:edea7d15772ceeb29db4aff55e482d4bcfb6ae160ce144f2682de02f6d693551"},
+ {file = "attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309"},
+ {file = "attrs-26.1.0.tar.gz", hash = "sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32"},
]
-[package.dependencies]
-aiosignal = ">=1.1.2"
-async-timeout = {version = ">=4.0,<5.0", markers = "python_version < \"3.11\""}
-attrs = ">=17.3.0"
-frozenlist = ">=1.1.1"
-multidict = ">=4.5,<7.0"
-yarl = ">=1.0,<2.0"
+[[package]]
+name = "backports-asyncio-runner"
+version = "1.2.0"
+description = "Backport of asyncio.Runner, a context manager that controls event loop life cycle."
+optional = false
+python-versions = "<3.11,>=3.8"
+files = [
+ {file = "backports_asyncio_runner-1.2.0-py3-none-any.whl", hash = "sha256:0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5"},
+ {file = "backports_asyncio_runner-1.2.0.tar.gz", hash = "sha256:a5aa7b2b7d8f8bfcaa2b57313f70792df84e32a2a746f585213373f900b42162"},
+]
-[package.extras]
-speedups = ["Brotli", "aiodns", "brotlicffi"]
+[[package]]
+name = "bracex"
+version = "2.6"
+description = "Bash style brace expander."
+optional = false
+python-versions = ">=3.9"
+files = [
+ {file = "bracex-2.6-py3-none-any.whl", hash = "sha256:0b0049264e7340b3ec782b5cb99beb325f36c3782a32e36e876452fd49a09952"},
+ {file = "bracex-2.6.tar.gz", hash = "sha256:98f1347cd77e22ee8d967a30ad4e310b233f7754dbf31ff3fceb76145ba47dc7"},
+]
[[package]]
-name = "aiosignal"
-version = "1.3.1"
-description = "aiosignal: a list of registered asynchronous callbacks"
+name = "certifi"
+version = "2026.5.20"
+description = "Python package for providing Mozilla's CA Bundle."
optional = false
python-versions = ">=3.7"
files = [
- {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"},
- {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"},
+ {file = "certifi-2026.5.20-py3-none-any.whl", hash = "sha256:3c52e209ba0a4ad7aebe60436a4ab349c39e1e602e8c134221e546902ad25897"},
+ {file = "certifi-2026.5.20.tar.gz", hash = "sha256:69dea482ab64caa7b9f6aba1c6bf48bb6a5448d1c0f1b17ab42ad8c763a5344d"},
+]
+
+[[package]]
+name = "colorama"
+version = "0.4.6"
+description = "Cross-platform colored terminal text."
+optional = false
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
+files = [
+ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
+ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
+]
+
+[[package]]
+name = "contourpy"
+version = "1.3.2"
+description = "Python library for calculating contours of 2D quadrilateral grids"
+optional = false
+python-versions = ">=3.10"
+files = [
+ {file = "contourpy-1.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ba38e3f9f330af820c4b27ceb4b9c7feee5fe0493ea53a8720f4792667465934"},
+ {file = "contourpy-1.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dc41ba0714aa2968d1f8674ec97504a8f7e334f48eeacebcaa6256213acb0989"},
+ {file = "contourpy-1.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9be002b31c558d1ddf1b9b415b162c603405414bacd6932d031c5b5a8b757f0d"},
+ {file = "contourpy-1.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8d2e74acbcba3bfdb6d9d8384cdc4f9260cae86ed9beee8bd5f54fee49a430b9"},
+ {file = "contourpy-1.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e259bced5549ac64410162adc973c5e2fb77f04df4a439d00b478e57a0e65512"},
+ {file = "contourpy-1.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad687a04bc802cbe8b9c399c07162a3c35e227e2daccf1668eb1f278cb698631"},
+ {file = "contourpy-1.3.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cdd22595308f53ef2f891040ab2b93d79192513ffccbd7fe19be7aa773a5e09f"},
+ {file = "contourpy-1.3.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b4f54d6a2defe9f257327b0f243612dd051cc43825587520b1bf74a31e2f6ef2"},
+ {file = "contourpy-1.3.2-cp310-cp310-win32.whl", hash = "sha256:f939a054192ddc596e031e50bb13b657ce318cf13d264f095ce9db7dc6ae81c0"},
+ {file = "contourpy-1.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:c440093bbc8fc21c637c03bafcbef95ccd963bc6e0514ad887932c18ca2a759a"},
+ {file = "contourpy-1.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6a37a2fb93d4df3fc4c0e363ea4d16f83195fc09c891bc8ce072b9d084853445"},
+ {file = "contourpy-1.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b7cd50c38f500bbcc9b6a46643a40e0913673f869315d8e70de0438817cb7773"},
+ {file = "contourpy-1.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6658ccc7251a4433eebd89ed2672c2ed96fba367fd25ca9512aa92a4b46c4f1"},
+ {file = "contourpy-1.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:70771a461aaeb335df14deb6c97439973d253ae70660ca085eec25241137ef43"},
+ {file = "contourpy-1.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65a887a6e8c4cd0897507d814b14c54a8c2e2aa4ac9f7686292f9769fcf9a6ab"},
+ {file = "contourpy-1.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3859783aefa2b8355697f16642695a5b9792e7a46ab86da1118a4a23a51a33d7"},
+ {file = "contourpy-1.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:eab0f6db315fa4d70f1d8ab514e527f0366ec021ff853d7ed6a2d33605cf4b83"},
+ {file = "contourpy-1.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d91a3ccc7fea94ca0acab82ceb77f396d50a1f67412efe4c526f5d20264e6ecd"},
+ {file = "contourpy-1.3.2-cp311-cp311-win32.whl", hash = "sha256:1c48188778d4d2f3d48e4643fb15d8608b1d01e4b4d6b0548d9b336c28fc9b6f"},
+ {file = "contourpy-1.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:5ebac872ba09cb8f2131c46b8739a7ff71de28a24c869bcad554477eb089a878"},
+ {file = "contourpy-1.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4caf2bcd2969402bf77edc4cb6034c7dd7c0803213b3523f111eb7460a51b8d2"},
+ {file = "contourpy-1.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:82199cb78276249796419fe36b7386bd8d2cc3f28b3bc19fe2454fe2e26c4c15"},
+ {file = "contourpy-1.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:106fab697af11456fcba3e352ad50effe493a90f893fca6c2ca5c033820cea92"},
+ {file = "contourpy-1.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d14f12932a8d620e307f715857107b1d1845cc44fdb5da2bc8e850f5ceba9f87"},
+ {file = "contourpy-1.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:532fd26e715560721bb0d5fc7610fce279b3699b018600ab999d1be895b09415"},
+ {file = "contourpy-1.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26b383144cf2d2c29f01a1e8170f50dacf0eac02d64139dcd709a8ac4eb3cfe"},
+ {file = "contourpy-1.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c49f73e61f1f774650a55d221803b101d966ca0c5a2d6d5e4320ec3997489441"},
+ {file = "contourpy-1.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3d80b2c0300583228ac98d0a927a1ba6a2ba6b8a742463c564f1d419ee5b211e"},
+ {file = "contourpy-1.3.2-cp312-cp312-win32.whl", hash = "sha256:90df94c89a91b7362e1142cbee7568f86514412ab8a2c0d0fca72d7e91b62912"},
+ {file = "contourpy-1.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:8c942a01d9163e2e5cfb05cb66110121b8d07ad438a17f9e766317bcb62abf73"},
+ {file = "contourpy-1.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:de39db2604ae755316cb5967728f4bea92685884b1e767b7c24e983ef5f771cb"},
+ {file = "contourpy-1.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3f9e896f447c5c8618f1edb2bafa9a4030f22a575ec418ad70611450720b5b08"},
+ {file = "contourpy-1.3.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71e2bd4a1c4188f5c2b8d274da78faab884b59df20df63c34f74aa1813c4427c"},
+ {file = "contourpy-1.3.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de425af81b6cea33101ae95ece1f696af39446db9682a0b56daaa48cfc29f38f"},
+ {file = "contourpy-1.3.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:977e98a0e0480d3fe292246417239d2d45435904afd6d7332d8455981c408b85"},
+ {file = "contourpy-1.3.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:434f0adf84911c924519d2b08fc10491dd282b20bdd3fa8f60fd816ea0b48841"},
+ {file = "contourpy-1.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c66c4906cdbc50e9cba65978823e6e00b45682eb09adbb78c9775b74eb222422"},
+ {file = "contourpy-1.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8b7fc0cd78ba2f4695fd0a6ad81a19e7e3ab825c31b577f384aa9d7817dc3bef"},
+ {file = "contourpy-1.3.2-cp313-cp313-win32.whl", hash = "sha256:15ce6ab60957ca74cff444fe66d9045c1fd3e92c8936894ebd1f3eef2fff075f"},
+ {file = "contourpy-1.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:e1578f7eafce927b168752ed7e22646dad6cd9bca673c60bff55889fa236ebf9"},
+ {file = "contourpy-1.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0475b1f6604896bc7c53bb070e355e9321e1bc0d381735421a2d2068ec56531f"},
+ {file = "contourpy-1.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c85bb486e9be652314bb5b9e2e3b0d1b2e643d5eec4992c0fbe8ac71775da739"},
+ {file = "contourpy-1.3.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:745b57db7758f3ffc05a10254edd3182a2a83402a89c00957a8e8a22f5582823"},
+ {file = "contourpy-1.3.2-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:970e9173dbd7eba9b4e01aab19215a48ee5dd3f43cef736eebde064a171f89a5"},
+ {file = "contourpy-1.3.2-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6c4639a9c22230276b7bffb6a850dfc8258a2521305e1faefe804d006b2e532"},
+ {file = "contourpy-1.3.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc829960f34ba36aad4302e78eabf3ef16a3a100863f0d4eeddf30e8a485a03b"},
+ {file = "contourpy-1.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d32530b534e986374fc19eaa77fcb87e8a99e5431499949b828312bdcd20ac52"},
+ {file = "contourpy-1.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e298e7e70cf4eb179cc1077be1c725b5fd131ebc81181bf0c03525c8abc297fd"},
+ {file = "contourpy-1.3.2-cp313-cp313t-win32.whl", hash = "sha256:d0e589ae0d55204991450bb5c23f571c64fe43adaa53f93fc902a84c96f52fe1"},
+ {file = "contourpy-1.3.2-cp313-cp313t-win_amd64.whl", hash = "sha256:78e9253c3de756b3f6a5174d024c4835acd59eb3f8e2ca13e775dbffe1558f69"},
+ {file = "contourpy-1.3.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:fd93cc7f3139b6dd7aab2f26a90dde0aa9fc264dbf70f6740d498a70b860b82c"},
+ {file = "contourpy-1.3.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:107ba8a6a7eec58bb475329e6d3b95deba9440667c4d62b9b6063942b61d7f16"},
+ {file = "contourpy-1.3.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ded1706ed0c1049224531b81128efbd5084598f18d8a2d9efae833edbd2b40ad"},
+ {file = "contourpy-1.3.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5f5964cdad279256c084b69c3f412b7801e15356b16efa9d78aa974041903da0"},
+ {file = "contourpy-1.3.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49b65a95d642d4efa8f64ba12558fcb83407e58a2dfba9d796d77b63ccfcaff5"},
+ {file = "contourpy-1.3.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:8c5acb8dddb0752bf252e01a3035b21443158910ac16a3b0d20e7fed7d534ce5"},
+ {file = "contourpy-1.3.2.tar.gz", hash = "sha256:b6945942715a034c671b7fc54f9588126b0b8bf23db2696e3ca8328f3ff0ab54"},
]
[package.dependencies]
-frozenlist = ">=1.1.0"
+numpy = ">=1.23"
+
+[package.extras]
+bokeh = ["bokeh", "selenium"]
+docs = ["furo", "sphinx (>=7.2)", "sphinx-copybutton"]
+mypy = ["bokeh", "contourpy[bokeh,docs]", "docutils-stubs", "mypy (==1.15.0)", "types-Pillow"]
+test = ["Pillow", "contourpy[test-no-images]", "matplotlib"]
+test-no-images = ["pytest", "pytest-cov", "pytest-rerunfailures", "pytest-xdist", "wurlitzer"]
[[package]]
-name = "annotated-types"
-version = "0.6.0"
-description = "Reusable constraint types to use with typing.Annotated"
+name = "cycler"
+version = "0.12.1"
+description = "Composable style cycles"
optional = false
python-versions = ">=3.8"
files = [
- {file = "annotated_types-0.6.0-py3-none-any.whl", hash = "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43"},
- {file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"},
+ {file = "cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30"},
+ {file = "cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c"},
]
-[package.dependencies]
-typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.9\""}
+[package.extras]
+docs = ["ipython", "matplotlib", "numpydoc", "sphinx"]
+tests = ["pytest", "pytest-cov", "pytest-xdist"]
[[package]]
-name = "async-timeout"
-version = "4.0.3"
-description = "Timeout context manager for asyncio programs"
+name = "dockerfile-parse"
+version = "2.0.1"
+description = "Python library for Dockerfile manipulation"
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.6"
files = [
- {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"},
- {file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"},
+ {file = "dockerfile-parse-2.0.1.tar.gz", hash = "sha256:3184ccdc513221983e503ac00e1aa504a2aa8f84e5de673c46b0b6eee99ec7bc"},
+ {file = "dockerfile_parse-2.0.1-py2.py3-none-any.whl", hash = "sha256:bdffd126d2eb26acf1066acb54cb2e336682e1d72b974a40894fac76a4df17f6"},
]
[[package]]
-name = "attrs"
-version = "23.2.0"
-description = "Classes Without Boilerplate"
+name = "e2b"
+version = "2.26.0"
+description = "E2B SDK that give agents cloud environments"
+optional = false
+python-versions = "<4.0,>=3.10"
+files = [
+ {file = "e2b-2.26.0-py3-none-any.whl", hash = "sha256:55cdb88b30d3026084fff862275815d88ffd37665814f73f09beea9c057de5bc"},
+ {file = "e2b-2.26.0.tar.gz", hash = "sha256:e140aec56c29a34706cdaf1bbe4dc1858ac38c7bed87145795019cf321866a2f"},
+]
+
+[package.dependencies]
+attrs = ">=23.2.0"
+dockerfile-parse = ">=2.0.1,<3.0.0"
+h2 = ">=4,<5"
+httpcore = ">=1.0.5,<2.0.0"
+httpx = ">=0.27.0,<1.0.0"
+packaging = ">=24.1"
+protobuf = ">=4.21.0"
+python-dateutil = ">=2.8.2"
+rich = ">=14.0.0"
+typing-extensions = ">=4.1.0"
+wcmatch = ">=10.1,<11.0"
+
+[[package]]
+name = "exceptiongroup"
+version = "1.3.1"
+description = "Backport of PEP 654 (exception groups)"
optional = false
python-versions = ">=3.7"
files = [
- {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"},
- {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"},
+ {file = "exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598"},
+ {file = "exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219"},
]
+[package.dependencies]
+typing-extensions = {version = ">=4.6.0", markers = "python_version < \"3.13\""}
+
[package.extras]
-cov = ["attrs[tests]", "coverage[toml] (>=5.3)"]
-dev = ["attrs[tests]", "pre-commit"]
-docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"]
-tests = ["attrs[tests-no-zope]", "zope-interface"]
-tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"]
-tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"]
+test = ["pytest (>=6)"]
[[package]]
-name = "black"
-version = "24.3.0"
-description = "The uncompromising code formatter."
+name = "execnet"
+version = "2.1.2"
+description = "execnet: rapid multi-Python deployment"
optional = false
python-versions = ">=3.8"
files = [
- {file = "black-24.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7d5e026f8da0322b5662fa7a8e752b3fa2dac1c1cbc213c3d7ff9bdd0ab12395"},
- {file = "black-24.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9f50ea1132e2189d8dff0115ab75b65590a3e97de1e143795adb4ce317934995"},
- {file = "black-24.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2af80566f43c85f5797365077fb64a393861a3730bd110971ab7a0c94e873e7"},
- {file = "black-24.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:4be5bb28e090456adfc1255e03967fb67ca846a03be7aadf6249096100ee32d0"},
- {file = "black-24.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4f1373a7808a8f135b774039f61d59e4be7eb56b2513d3d2f02a8b9365b8a8a9"},
- {file = "black-24.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aadf7a02d947936ee418777e0247ea114f78aff0d0959461057cae8a04f20597"},
- {file = "black-24.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c02e4ea2ae09d16314d30912a58ada9a5c4fdfedf9512d23326128ac08ac3d"},
- {file = "black-24.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:bf21b7b230718a5f08bd32d5e4f1db7fc8788345c8aea1d155fc17852b3410f5"},
- {file = "black-24.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:2818cf72dfd5d289e48f37ccfa08b460bf469e67fb7c4abb07edc2e9f16fb63f"},
- {file = "black-24.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4acf672def7eb1725f41f38bf6bf425c8237248bb0804faa3965c036f7672d11"},
- {file = "black-24.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7ed6668cbbfcd231fa0dc1b137d3e40c04c7f786e626b405c62bcd5db5857e4"},
- {file = "black-24.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:56f52cfbd3dabe2798d76dbdd299faa046a901041faf2cf33288bc4e6dae57b5"},
- {file = "black-24.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:79dcf34b33e38ed1b17434693763301d7ccbd1c5860674a8f871bd15139e7837"},
- {file = "black-24.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e19cb1c6365fd6dc38a6eae2dcb691d7d83935c10215aef8e6c38edee3f77abd"},
- {file = "black-24.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65b76c275e4c1c5ce6e9870911384bff5ca31ab63d19c76811cb1fb162678213"},
- {file = "black-24.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:b5991d523eee14756f3c8d5df5231550ae8993e2286b8014e2fdea7156ed0959"},
- {file = "black-24.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c45f8dff244b3c431b36e3224b6be4a127c6aca780853574c00faf99258041eb"},
- {file = "black-24.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6905238a754ceb7788a73f02b45637d820b2f5478b20fec82ea865e4f5d4d9f7"},
- {file = "black-24.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7de8d330763c66663661a1ffd432274a2f92f07feeddd89ffd085b5744f85e7"},
- {file = "black-24.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:7bb041dca0d784697af4646d3b62ba4a6b028276ae878e53f6b4f74ddd6db99f"},
- {file = "black-24.3.0-py3-none-any.whl", hash = "sha256:41622020d7120e01d377f74249e677039d20e6344ff5851de8a10f11f513bf93"},
- {file = "black-24.3.0.tar.gz", hash = "sha256:a0c9c4a0771afc6919578cec71ce82a3e31e054904e7197deacbc9382671c41f"},
+ {file = "execnet-2.1.2-py3-none-any.whl", hash = "sha256:67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec"},
+ {file = "execnet-2.1.2.tar.gz", hash = "sha256:63d83bfdd9a23e35b9c6a3261412324f964c2ec8dcd8d3c6916ee9373e0befcd"},
]
-[package.dependencies]
-click = ">=8.0.0"
-mypy-extensions = ">=0.4.3"
-packaging = ">=22.0"
-pathspec = ">=0.9.0"
-platformdirs = ">=2"
-tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
-typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""}
-
[package.extras]
-colorama = ["colorama (>=0.4.3)"]
-d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"]
-jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
-uvloop = ["uvloop (>=0.15.2)"]
+testing = ["hatch", "pre-commit", "pytest", "tox"]
[[package]]
-name = "certifi"
-version = "2024.2.2"
-description = "Python package for providing Mozilla's CA Bundle."
+name = "fonttools"
+version = "4.63.0"
+description = "Tools to manipulate font files"
optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.10"
files = [
- {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"},
- {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"},
+ {file = "fonttools-4.63.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e3297a6a4059b4acc3a1e9a8b04741f240a80044eef08ebd32e8b5bcdddce75b"},
+ {file = "fonttools-4.63.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b1cd75a03ad8cb5bc40c90bfde68c0c47de423aa19e5c0f362b43520645eea94"},
+ {file = "fonttools-4.63.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c0425b277a59cff3d80ca42162a8de360f318438a2ac83570842a678d826d579"},
+ {file = "fonttools-4.63.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d7e5c9973aa04c95650c96e5f5ad865fbf42d62079163ecfab1e01cbc2504c22"},
+ {file = "fonttools-4.63.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cb014d58140a38135f16064c74c652ed57aa0b75cbf8bb59cac821f7edb5334e"},
+ {file = "fonttools-4.63.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:032038247a96c1690f9f31e377c389383c902531b085aa4e4dabd6f57f870e69"},
+ {file = "fonttools-4.63.0-cp310-cp310-win32.whl", hash = "sha256:a8b33a82979e0a6a34ff435cc81317be1f95ec1ebb7a3a2d1c8a6a54f02ae44e"},
+ {file = "fonttools-4.63.0-cp310-cp310-win_amd64.whl", hash = "sha256:0c18358a155d75034911c5ee397a5b44cd19dd325dbb8b35fb60bf421d6a72ac"},
+ {file = "fonttools-4.63.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2b8ae05d9eacf6081414d759c0a352769ac28ce31280d6bb8e77b03f9e3c449f"},
+ {file = "fonttools-4.63.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:79cdc9f567aec74a72918fd060283911406750cbc9fd28c1316023deb6ce31a9"},
+ {file = "fonttools-4.63.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2c14b4fd138c4bafcca294765c547914e1aa431ae1ca94ab99d8db08c958bd3b"},
+ {file = "fonttools-4.63.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d76ac49f929aecaf82d83250b8347e099d7aecba0f4726c1d9b6df3b8bb5fe18"},
+ {file = "fonttools-4.63.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:dcf076a4474fe0d7367e5bbf5b052c7284fa1feca729c04176ce513521afd8a0"},
+ {file = "fonttools-4.63.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7dd683fef0663e9f0f45cf541d788d24caa3ec9db50796b588e1757d8b3bc007"},
+ {file = "fonttools-4.63.0-cp311-cp311-win32.whl", hash = "sha256:afefc1ed0a59785a7fb06ea7e1678e849c193e1e387db783579bc7b3056fcfcb"},
+ {file = "fonttools-4.63.0-cp311-cp311-win_amd64.whl", hash = "sha256:063e08bd17bd5a90127a14123de0d6a952dbc847695fd98b63c043d58057f90c"},
+ {file = "fonttools-4.63.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:37dd23e621e3b0aef1baa70a303b80aaf38449632cfc8fd2a55fb285bbccfc02"},
+ {file = "fonttools-4.63.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a9faff9e0c1f76f9fd55899d2ce785832efebab37eb8ae13995853aef178bef0"},
+ {file = "fonttools-4.63.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ef3048ef05dbb552b89817713d9cac912e00d0fde4a3105c00d29e52e10c89af"},
+ {file = "fonttools-4.63.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:58dc6bb86a78d782f00f9190ca02c119cf5bbe2807536e361e18d42019f877d8"},
+ {file = "fonttools-4.63.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ee08ebfa58f6e1aeff5697ab9582105bb620008c1caafb681e4c557e7483027b"},
+ {file = "fonttools-4.63.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:27fdc65af8da6f88b9c6121c47a464cbe359fcfff7ff6fc2d37a1f395d755b78"},
+ {file = "fonttools-4.63.0-cp312-cp312-win32.whl", hash = "sha256:af2fd1664d00a397d75f806985ddb36282091c2131a73a6485c23b4a34722263"},
+ {file = "fonttools-4.63.0-cp312-cp312-win_amd64.whl", hash = "sha256:59ac449f8cca9b4ffa08d2e7bbadad87ce710d69d1eda5c3c1ce579baa987272"},
+ {file = "fonttools-4.63.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:cd7e9857e5e63738b9d9fd707bc1f59c8b09e5177726d23664db393c59bb08bd"},
+ {file = "fonttools-4.63.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c2a2a42198b696a6f48fad91709afb55176e66a5e566131219dba372fb7f8c59"},
+ {file = "fonttools-4.63.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e874792a8212b44583ea02189d9e693906b2f78b261f372f95d6c563210ac1d"},
+ {file = "fonttools-4.63.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:22135da48a348785c5e2d5d2d9d6bec5ed44adacbaeb9db12d9493bf6c6bfa68"},
+ {file = "fonttools-4.63.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ccf41f2efdf56994d22d73bef4ced1052161958169428d06ba9724ea9e9a64be"},
+ {file = "fonttools-4.63.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9ced0bd02ac751dd6319b0da88aaef24414e3b0dbc32bb4f24944821a3741a27"},
+ {file = "fonttools-4.63.0-cp313-cp313-win32.whl", hash = "sha256:85be818f5506e8a7753153def2c9550178f0ecae6a47b5e0e8dbb23f7cc90380"},
+ {file = "fonttools-4.63.0-cp313-cp313-win_amd64.whl", hash = "sha256:ba04cb5891d4c0c21b6da95eda8d7b090021508a294fff33464fc7d241e0856b"},
+ {file = "fonttools-4.63.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:fd1e3094f42d806d3d7c79162fc59e5910fcbe3a7360c385b8da969bc4493745"},
+ {file = "fonttools-4.63.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:6e528da43bc3791085f8cb6141b1d13e459226790240340fcbb4625649238b03"},
+ {file = "fonttools-4.63.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b2248c5decb223562f7902ff6325077a073f608ee8e33e88ad88db734eb9f49"},
+ {file = "fonttools-4.63.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:308f957cdeaf8abe4e5f2f124902ef405448af92c90f80e302a3b771c2e6116b"},
+ {file = "fonttools-4.63.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:bf00f21eb5fb721dbaf73d1e9da6d02a1af7768f2ebcf9798be98beab8ba90f6"},
+ {file = "fonttools-4.63.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c1aaa4b9c75798400ac043ce04d74e7830376c85095a5a6ed7cba2f17a266bf4"},
+ {file = "fonttools-4.63.0-cp314-cp314-win32.whl", hash = "sha256:22693918177bd9ceabec4736d338045f357769416fc6b0b2508eefef75b08616"},
+ {file = "fonttools-4.63.0-cp314-cp314-win_amd64.whl", hash = "sha256:7d782fac32985914c351556f68ac0855391572bcd87de50e05970d3cd4c96fc5"},
+ {file = "fonttools-4.63.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:6db5140a60a5d731d21ec076745b40a310607731b0a565b50776393188649001"},
+ {file = "fonttools-4.63.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7d76edbff9014094dbf03bd2d074709dfa6ec7aba13d838c937a2b33d2d6a86e"},
+ {file = "fonttools-4.63.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0eac00b9118c3c2f87d272e45341871c5b3066baa3c86897fa634a7c3fb59096"},
+ {file = "fonttools-4.63.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:51394295f1a51de8b5f30bdb1e1b9a4231536c7064ef5c6e211eec19fa36036f"},
+ {file = "fonttools-4.63.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:9e12f105d2b6342c559c298afb674006bb2893afc7102dcf8a1b55b0486b4e40"},
+ {file = "fonttools-4.63.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:796f27556dbe094c4824f75ca85267e4df776c79036c8441469a4df37038c196"},
+ {file = "fonttools-4.63.0-cp314-cp314t-win32.whl", hash = "sha256:948428a275741f0b64b113c955425a953314f4b9ab9997f73a72c83e68e569c8"},
+ {file = "fonttools-4.63.0-cp314-cp314t-win_amd64.whl", hash = "sha256:6d4741eb179121cab9eea4cb2393d24492373a260d7945006358c08cfbf45419"},
+ {file = "fonttools-4.63.0-py3-none-any.whl", hash = "sha256:445af2eab030a16b9171ea8bdda7ebf7d96bda2df88ee182a464252f6e05e20d"},
+ {file = "fonttools-4.63.0.tar.gz", hash = "sha256:caeb583deeb5168e694b65cda8b4ee62abedfa66cf88488734466f2366b9c4e0"},
]
+[package.extras]
+all = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "lxml (>=4.0)", "lz4 (>=1.7.4.2)", "matplotlib", "munkres", "pycairo", "scipy", "skia-pathops (>=0.5.0)", "sympy", "uharfbuzz (>=0.45.0)", "unicodedata2 (>=17.0.0)", "xattr", "zopfli (>=0.1.4)"]
+graphite = ["lz4 (>=1.7.4.2)"]
+interpolatable = ["munkres", "pycairo", "scipy"]
+lxml = ["lxml (>=4.0)"]
+pathops = ["skia-pathops (>=0.5.0)"]
+plot = ["matplotlib"]
+repacker = ["uharfbuzz (>=0.45.0)"]
+symfont = ["sympy"]
+type1 = ["xattr"]
+unicode = ["unicodedata2 (>=17.0.0)"]
+woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"]
+
[[package]]
-name = "charset-normalizer"
-version = "3.3.2"
-description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
+name = "h11"
+version = "0.16.0"
+description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
optional = false
-python-versions = ">=3.7.0"
+python-versions = ">=3.8"
files = [
- {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"},
- {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"},
- {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"},
- {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"},
- {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"},
- {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"},
- {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"},
- {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"},
- {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"},
- {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"},
- {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"},
- {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"},
- {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"},
- {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"},
- {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"},
- {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"},
- {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"},
- {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"},
- {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"},
- {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"},
+ {file = "h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86"},
+ {file = "h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1"},
]
[[package]]
-name = "click"
-version = "8.1.7"
-description = "Composable command line interface toolkit"
+name = "h2"
+version = "4.3.0"
+description = "Pure-Python HTTP/2 protocol implementation"
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.9"
files = [
- {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
- {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
+ {file = "h2-4.3.0-py3-none-any.whl", hash = "sha256:c438f029a25f7945c69e0ccf0fb951dc3f73a5f6412981daee861431b70e2bdd"},
+ {file = "h2-4.3.0.tar.gz", hash = "sha256:6c59efe4323fa18b47a632221a1888bd7fde6249819beda254aeca909f221bf1"},
]
[package.dependencies]
-colorama = {version = "*", markers = "platform_system == \"Windows\""}
+hpack = ">=4.1,<5"
+hyperframe = ">=6.1,<7"
[[package]]
-name = "colorama"
-version = "0.4.6"
-description = "Cross-platform colored terminal text."
+name = "hpack"
+version = "4.1.0"
+description = "Pure-Python HPACK header encoding"
optional = false
-python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
+python-versions = ">=3.9"
files = [
- {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
- {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
+ {file = "hpack-4.1.0-py3-none-any.whl", hash = "sha256:157ac792668d995c657d93111f46b4535ed114f0c9c8d672271bbec7eae1b496"},
+ {file = "hpack-4.1.0.tar.gz", hash = "sha256:ec5eca154f7056aa06f196a557655c5b009b382873ac8d1e66e79e87535f1dca"},
]
[[package]]
-name = "e2b"
-version = "0.17.0"
-description = "E2B SDK that give agents cloud environments"
+name = "httpcore"
+version = "1.0.9"
+description = "A minimal low-level HTTP client."
optional = false
-python-versions = "<4.0,>=3.8"
+python-versions = ">=3.8"
files = [
- {file = "e2b-0.17.0-py3-none-any.whl", hash = "sha256:4ac1905ba9801d566d8c4fca2558c74e622c06757b43550cf31f66055acc43c5"},
- {file = "e2b-0.17.0.tar.gz", hash = "sha256:64b71ff10fe5183ec3c9c7a643de9a89f3e4f00180c7732c6a2beb5c090d04b8"},
+ {file = "httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55"},
+ {file = "httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8"},
]
[package.dependencies]
-aenum = ">=3.1.11"
-aiohttp = ">=3.8.4"
-jsonrpcclient = ">=4.0.3"
-pydantic = "*"
-python-dateutil = ">=2.8.2"
-requests = ">=2.31.0"
-typing-extensions = ">=4.8.0"
-urllib3 = ">=1.25.3"
-websockets = ">=11.0.3"
+certifi = "*"
+h11 = ">=0.16"
+
+[package.extras]
+asyncio = ["anyio (>=4.0,<5.0)"]
+http2 = ["h2 (>=3,<5)"]
+socks = ["socksio (==1.*)"]
+trio = ["trio (>=0.22.0,<1.0)"]
[[package]]
-name = "exceptiongroup"
-version = "1.2.0"
-description = "Backport of PEP 654 (exception groups)"
+name = "httpx"
+version = "0.28.1"
+description = "The next generation HTTP client."
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"},
- {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"},
+ {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"},
+ {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"},
]
+[package.dependencies]
+anyio = "*"
+certifi = "*"
+httpcore = "==1.*"
+idna = "*"
+
[package.extras]
-test = ["pytest (>=6)"]
+brotli = ["brotli", "brotlicffi"]
+cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"]
+http2 = ["h2 (>=3,<5)"]
+socks = ["socksio (==1.*)"]
+zstd = ["zstandard (>=0.18.0)"]
[[package]]
-name = "frozenlist"
-version = "1.4.1"
-description = "A list-like structure which implements collections.abc.MutableSequence"
+name = "hyperframe"
+version = "6.1.0"
+description = "Pure-Python HTTP/2 framing"
optional = false
-python-versions = ">=3.8"
+python-versions = ">=3.9"
files = [
- {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac"},
- {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868"},
- {file = "frozenlist-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:74fb4bee6880b529a0c6560885fce4dc95936920f9f20f53d99a213f7bf66776"},
- {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:590344787a90ae57d62511dd7c736ed56b428f04cd8c161fcc5e7232c130c69a"},
- {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:068b63f23b17df8569b7fdca5517edef76171cf3897eb68beb01341131fbd2ad"},
- {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c849d495bf5154cd8da18a9eb15db127d4dba2968d88831aff6f0331ea9bd4c"},
- {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9750cc7fe1ae3b1611bb8cfc3f9ec11d532244235d75901fb6b8e42ce9229dfe"},
- {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9b2de4cf0cdd5bd2dee4c4f63a653c61d2408055ab77b151c1957f221cabf2a"},
- {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98"},
- {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:27657df69e8801be6c3638054e202a135c7f299267f1a55ed3a598934f6c0d75"},
- {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:f9a3ea26252bd92f570600098783d1371354d89d5f6b7dfd87359d669f2109b5"},
- {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:4f57dab5fe3407b6c0c1cc907ac98e8a189f9e418f3b6e54d65a718aaafe3950"},
- {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e02a0e11cf6597299b9f3bbd3f93d79217cb90cfd1411aec33848b13f5c656cc"},
- {file = "frozenlist-1.4.1-cp310-cp310-win32.whl", hash = "sha256:a828c57f00f729620a442881cc60e57cfcec6842ba38e1b19fd3e47ac0ff8dc1"},
- {file = "frozenlist-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:f56e2333dda1fe0f909e7cc59f021eba0d2307bc6f012a1ccf2beca6ba362439"},
- {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0"},
- {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49"},
- {file = "frozenlist-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced"},
- {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0"},
- {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106"},
- {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068"},
- {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2"},
- {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19"},
- {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82"},
- {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec"},
- {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a"},
- {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74"},
- {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2"},
- {file = "frozenlist-1.4.1-cp311-cp311-win32.whl", hash = "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17"},
- {file = "frozenlist-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825"},
- {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae"},
- {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb"},
- {file = "frozenlist-1.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b"},
- {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86"},
- {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480"},
- {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09"},
- {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a"},
- {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd"},
- {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6"},
- {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1"},
- {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b"},
- {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e"},
- {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8"},
- {file = "frozenlist-1.4.1-cp312-cp312-win32.whl", hash = "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89"},
- {file = "frozenlist-1.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5"},
- {file = "frozenlist-1.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:20b51fa3f588ff2fe658663db52a41a4f7aa6c04f6201449c6c7c476bd255c0d"},
- {file = "frozenlist-1.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:410478a0c562d1a5bcc2f7ea448359fcb050ed48b3c6f6f4f18c313a9bdb1826"},
- {file = "frozenlist-1.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c6321c9efe29975232da3bd0af0ad216800a47e93d763ce64f291917a381b8eb"},
- {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48f6a4533887e189dae092f1cf981f2e3885175f7a0f33c91fb5b7b682b6bab6"},
- {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6eb73fa5426ea69ee0e012fb59cdc76a15b1283d6e32e4f8dc4482ec67d1194d"},
- {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fbeb989b5cc29e8daf7f976b421c220f1b8c731cbf22b9130d8815418ea45887"},
- {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32453c1de775c889eb4e22f1197fe3bdfe457d16476ea407472b9442e6295f7a"},
- {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693945278a31f2086d9bf3df0fe8254bbeaef1fe71e1351c3bd730aa7d31c41b"},
- {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1d0ce09d36d53bbbe566fe296965b23b961764c0bcf3ce2fa45f463745c04701"},
- {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3a670dc61eb0d0eb7080890c13de3066790f9049b47b0de04007090807c776b0"},
- {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:dca69045298ce5c11fd539682cff879cc1e664c245d1c64da929813e54241d11"},
- {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a06339f38e9ed3a64e4c4e43aec7f59084033647f908e4259d279a52d3757d09"},
- {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b7f2f9f912dca3934c1baec2e4585a674ef16fe00218d833856408c48d5beee7"},
- {file = "frozenlist-1.4.1-cp38-cp38-win32.whl", hash = "sha256:e7004be74cbb7d9f34553a5ce5fb08be14fb33bc86f332fb71cbe5216362a497"},
- {file = "frozenlist-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:5a7d70357e7cee13f470c7883a063aae5fe209a493c57d86eb7f5a6f910fae09"},
- {file = "frozenlist-1.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bfa4a17e17ce9abf47a74ae02f32d014c5e9404b6d9ac7f729e01562bbee601e"},
- {file = "frozenlist-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b7e3ed87d4138356775346e6845cccbe66cd9e207f3cd11d2f0b9fd13681359d"},
- {file = "frozenlist-1.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c99169d4ff810155ca50b4da3b075cbde79752443117d89429595c2e8e37fed8"},
- {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edb678da49d9f72c9f6c609fbe41a5dfb9a9282f9e6a2253d5a91e0fc382d7c0"},
- {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6db4667b187a6742b33afbbaf05a7bc551ffcf1ced0000a571aedbb4aa42fc7b"},
- {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55fdc093b5a3cb41d420884cdaf37a1e74c3c37a31f46e66286d9145d2063bd0"},
- {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82e8211d69a4f4bc360ea22cd6555f8e61a1bd211d1d5d39d3d228b48c83a897"},
- {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89aa2c2eeb20957be2d950b85974b30a01a762f3308cd02bb15e1ad632e22dc7"},
- {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9d3e0c25a2350080e9319724dede4f31f43a6c9779be48021a7f4ebde8b2d742"},
- {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7268252af60904bf52c26173cbadc3a071cece75f873705419c8681f24d3edea"},
- {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:0c250a29735d4f15321007fb02865f0e6b6a41a6b88f1f523ca1596ab5f50bd5"},
- {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:96ec70beabbd3b10e8bfe52616a13561e58fe84c0101dd031dc78f250d5128b9"},
- {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:23b2d7679b73fe0e5a4560b672a39f98dfc6f60df63823b0a9970525325b95f6"},
- {file = "frozenlist-1.4.1-cp39-cp39-win32.whl", hash = "sha256:a7496bfe1da7fb1a4e1cc23bb67c58fab69311cc7d32b5a99c2007b4b2a0e932"},
- {file = "frozenlist-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:e6a20a581f9ce92d389a8c7d7c3dd47c81fd5d6e655c8dddf341e14aa48659d0"},
- {file = "frozenlist-1.4.1-py3-none-any.whl", hash = "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7"},
- {file = "frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b"},
+ {file = "hyperframe-6.1.0-py3-none-any.whl", hash = "sha256:b03380493a519fce58ea5af42e4a42317bf9bd425596f7a0835ffce80f1a42e5"},
+ {file = "hyperframe-6.1.0.tar.gz", hash = "sha256:f630908a00854a7adeabd6382b43923a4c4cd4b821fcb527e6ab9e15382a3b08"},
]
[[package]]
name = "idna"
-version = "3.7"
+version = "3.16"
description = "Internationalized Domain Names in Applications (IDNA)"
optional = false
-python-versions = ">=3.5"
+python-versions = ">=3.9"
files = [
- {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"},
- {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"},
+ {file = "idna-3.16-py3-none-any.whl", hash = "sha256:cc246e3a3f89580c3a951b5ad298ca4638078b2cdd4f115654332b5c26daded5"},
+ {file = "idna-3.16.tar.gz", hash = "sha256:d7a6da03db833450fca25d2358ac9ff06cd624577a4aea3a596d5c0f77b8e03d"},
]
+[package.extras]
+all = ["mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"]
+
[[package]]
name = "iniconfig"
-version = "2.0.0"
+version = "2.3.0"
description = "brain-dead simple config-ini parsing"
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.10"
files = [
- {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"},
- {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
+ {file = "iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12"},
+ {file = "iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730"},
]
[[package]]
-name = "jsonrpcclient"
-version = "4.0.3"
-description = "Send JSON-RPC requests"
+name = "kiwisolver"
+version = "1.5.0"
+description = "A fast implementation of the Cassowary constraint solver"
optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.10"
+files = [
+ {file = "kiwisolver-1.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:32cc0a5365239a6ea0c6ed461e8838d053b57e397443c0ca894dcc8e388d4374"},
+ {file = "kiwisolver-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cc0b66c1eec9021353a4b4483afb12dfd50e3669ffbb9152d6842eb34c7e29fd"},
+ {file = "kiwisolver-1.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:86e0287879f75621ae85197b0877ed2f8b7aa57b511c7331dce2eb6f4de7d476"},
+ {file = "kiwisolver-1.5.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:62f59da443c4f4849f73a51a193b1d9d258dcad0c41bc4d1b8fb2bcc04bfeb22"},
+ {file = "kiwisolver-1.5.0-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9190426b7aa26c5229501fa297b8d0653cfd3f5a36f7990c264e157cbf886b3b"},
+ {file = "kiwisolver-1.5.0-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c8277104ded0a51e699c8c3aff63ce2c56d4ed5519a5f73e0fd7057f959a2b9e"},
+ {file = "kiwisolver-1.5.0-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8f9baf6f0a6e7571c45c8863010b45e837c3ee1c2c77fcd6ef423be91b21fedb"},
+ {file = "kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cff8e5383db4989311f99e814feeb90c4723eb4edca425b9d5d9c3fefcdd9537"},
+ {file = "kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:ebae99ed6764f2b5771c522477b311be313e8841d2e0376db2b10922daebbba4"},
+ {file = "kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:d5cd5189fc2b6a538b75ae45433140c4823463918f7b1617c31e68b085c0022c"},
+ {file = "kiwisolver-1.5.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f42c23db5d1521218a3276bb08666dcb662896a0be7347cba864eca45ff64ede"},
+ {file = "kiwisolver-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:94eff26096eb5395136634622515b234ecb6c9979824c1f5004c6e3c3c85ccd2"},
+ {file = "kiwisolver-1.5.0-cp310-cp310-win_arm64.whl", hash = "sha256:dd952e03bfbb096cfe2dd35cd9e00f269969b67536cb4370994afc20ff2d0875"},
+ {file = "kiwisolver-1.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9eed0f7edbb274413b6ee781cca50541c8c0facd3d6fd289779e494340a2b85c"},
+ {file = "kiwisolver-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c4923e404d6bcd91b6779c009542e5647fef32e4a5d75e115e3bbac6f2335eb"},
+ {file = "kiwisolver-1.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0df54df7e686afa55e6f21fb86195224a6d9beb71d637e8d7920c95cf0f89aac"},
+ {file = "kiwisolver-1.5.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2517e24d7315eb51c10664cdb865195df38ab74456c677df67bb47f12d088a27"},
+ {file = "kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff710414307fefa903e0d9bdf300972f892c23477829f49504e59834f4195398"},
+ {file = "kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6176c1811d9d5a04fa391c490cc44f451e240697a16977f11c6f722efb9041db"},
+ {file = "kiwisolver-1.5.0-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50847dca5d197fcbd389c805aa1a1cf32f25d2e7273dc47ab181a517666b68cc"},
+ {file = "kiwisolver-1.5.0-cp311-cp311-manylinux_2_39_riscv64.whl", hash = "sha256:01808c6d15f4c3e8559595d6d1fe6411c68e4a3822b4b9972b44473b24f4e679"},
+ {file = "kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f1f9f4121ec58628c96baa3de1a55a4e3a333c5102c8e94b64e23bf7b2083309"},
+ {file = "kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b7d335370ae48a780c6e6a6bbfa97342f563744c39c35562f3f367665f5c1de2"},
+ {file = "kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:800ee55980c18545af444d93fdd60c56b580db5cc54867d8cbf8a1dc0829938c"},
+ {file = "kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c438f6ca858697c9ab67eb28246c92508af972e114cac34e57a6d4ba17a3ac08"},
+ {file = "kiwisolver-1.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8c63c91f95173f9c2a67c7c526b2cea976828a0e7fced9cdcead2802dc10f8a4"},
+ {file = "kiwisolver-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:beb7f344487cdcb9e1efe4b7a29681b74d34c08f0043a327a74da852a6749e7b"},
+ {file = "kiwisolver-1.5.0-cp311-cp311-win_arm64.whl", hash = "sha256:ad4ae4ffd1ee9cd11357b4c66b612da9888f4f4daf2f36995eda64bd45370cac"},
+ {file = "kiwisolver-1.5.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:4e9750bc21b886308024f8a54ccb9a2cc38ac9fa813bf4348434e3d54f337ff9"},
+ {file = "kiwisolver-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:72ec46b7eba5b395e0a7b63025490d3214c11013f4aacb4f5e8d6c3041829588"},
+ {file = "kiwisolver-1.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ed3a984b31da7481b103f68776f7128a89ef26ed40f4dc41a2223cda7fb24819"},
+ {file = "kiwisolver-1.5.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bb5136fb5352d3f422df33f0c879a1b0c204004324150cc3b5e3c4f310c9049f"},
+ {file = "kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b2af221f268f5af85e776a73d62b0845fc8baf8ef0abfae79d29c77d0e776aaf"},
+ {file = "kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b0f172dc8ffaccb8522d7c5d899de00133f2f1ca7b0a49b7da98e901de87bf2d"},
+ {file = "kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6ab8ba9152203feec73758dad83af9a0bbe05001eb4639e547207c40cfb52083"},
+ {file = "kiwisolver-1.5.0-cp312-cp312-manylinux_2_39_riscv64.whl", hash = "sha256:cdee07c4d7f6d72008d3f73b9bf027f4e11550224c7c50d8df1ae4a37c1402a6"},
+ {file = "kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7c60d3c9b06fb23bd9c6139281ccbdc384297579ae037f08ae90c69f6845c0b1"},
+ {file = "kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e315e5ec90d88e140f57696ff85b484ff68bb311e36f2c414aa4286293e6dee0"},
+ {file = "kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:1465387ac63576c3e125e5337a6892b9e99e0627d52317f3ca79e6930d889d15"},
+ {file = "kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:530a3fd64c87cffa844d4b6b9768774763d9caa299e9b75d8eca6a4423b31314"},
+ {file = "kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1d9daea4ea6b9be74fe2f01f7fbade8d6ffab263e781274cffca0dba9be9eec9"},
+ {file = "kiwisolver-1.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:f18c2d9782259a6dc132fdc7a63c168cbc74b35284b6d75c673958982a378384"},
+ {file = "kiwisolver-1.5.0-cp312-cp312-win_arm64.whl", hash = "sha256:f7c7553b13f69c1b29a5bde08ddc6d9d0c8bfb84f9ed01c30db25944aeb852a7"},
+ {file = "kiwisolver-1.5.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:fd40bb9cd0891c4c3cb1ddf83f8bbfa15731a248fdc8162669405451e2724b09"},
+ {file = "kiwisolver-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c0e1403fd7c26d77c1f03e096dc58a5c726503fa0db0456678b8668f76f521e3"},
+ {file = "kiwisolver-1.5.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dda366d548e89a90d88a86c692377d18d8bd64b39c1fb2b92cb31370e2896bbd"},
+ {file = "kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:332b4f0145c30b5f5ad9374881133e5aa64320428a57c2c2b61e9d891a51c2f3"},
+ {file = "kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c50b89ffd3e1a911c69a1dd3de7173c0cd10b130f56222e57898683841e4f96"},
+ {file = "kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4db576bb8c3ef9365f8b40fe0f671644de6736ae2c27a2c62d7d8a1b4329f099"},
+ {file = "kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0b85aad90cea8ac6797a53b5d5f2e967334fa4d1149f031c4537569972596cb8"},
+ {file = "kiwisolver-1.5.0-cp313-cp313-manylinux_2_39_riscv64.whl", hash = "sha256:d36ca54cb4c6c4686f7cbb7b817f66f5911c12ddb519450bbe86707155028f87"},
+ {file = "kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:38f4a703656f493b0ad185211ccfca7f0386120f022066b018eb5296d8613e23"},
+ {file = "kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3ac2360e93cb41be81121755c6462cff3beaa9967188c866e5fce5cf13170859"},
+ {file = "kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c95cab08d1965db3d84a121f1c7ce7479bdd4072c9b3dafd8fecce48a2e6b902"},
+ {file = "kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fc20894c3d21194d8041a28b65622d5b86db786da6e3cfe73f0c762951a61167"},
+ {file = "kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7a32f72973f0f950c1920475d5c5ea3d971b81b6f0ec53b8d0a956cc965f22e0"},
+ {file = "kiwisolver-1.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bf3acf1419fa93064a4c2189ac0b58e3be7872bf6ee6177b0d4c63dc4cea276"},
+ {file = "kiwisolver-1.5.0-cp313-cp313-win_arm64.whl", hash = "sha256:fa8eb9ecdb7efb0b226acec134e0d709e87a909fa4971a54c0c4f6e88635484c"},
+ {file = "kiwisolver-1.5.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:db485b3847d182b908b483b2ed133c66d88d49cacf98fd278fadafe11b4478d1"},
+ {file = "kiwisolver-1.5.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:be12f931839a3bdfe28b584db0e640a65a8bcbc24560ae3fdb025a449b3d754e"},
+ {file = "kiwisolver-1.5.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:16b85d37c2cbb3253226d26e64663f755d88a03439a9c47df6246b35defbdfb7"},
+ {file = "kiwisolver-1.5.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4432b835675f0ea7414aab3d37d119f7226d24869b7a829caeab49ebda407b0c"},
+ {file = "kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b0feb50971481a2cc44d94e88bdb02cdd497618252ae226b8eb1201b957e368"},
+ {file = "kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56fa888f10d0f367155e76ce849fa1166fc9730d13bd2d65a2aa13b6f5424489"},
+ {file = "kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:940dda65d5e764406b9fb92761cbf462e4e63f712ab60ed98f70552e496f3bf1"},
+ {file = "kiwisolver-1.5.0-cp313-cp313t-manylinux_2_39_riscv64.whl", hash = "sha256:89fc958c702ee9a745e4700378f5d23fddbc46ff89e8fdbf5395c24d5c1452a3"},
+ {file = "kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9027d773c4ff81487181a925945743413f6069634d0b122d0b37684ccf4f1e18"},
+ {file = "kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:5b233ea3e165e43e35dba1d2b8ecc21cf070b45b65ae17dd2747d2713d942021"},
+ {file = "kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:ce9bf03dad3b46408c08649c6fbd6ca28a9fce0eb32fdfffa6775a13103b5310"},
+ {file = "kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:fc4d3f1fb9ca0ae9f97b095963bc6326f1dbfd3779d6679a1e016b9baaa153d3"},
+ {file = "kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f443b4825c50a51ee68585522ab4a1d1257fac65896f282b4c6763337ac9f5d2"},
+ {file = "kiwisolver-1.5.0-cp313-cp313t-win_arm64.whl", hash = "sha256:893ff3a711d1b515ba9da14ee090519bad4610ed1962fbe298a434e8c5f8db53"},
+ {file = "kiwisolver-1.5.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8df31fe574b8b3993cc61764f40941111b25c2d9fea13d3ce24a49907cd2d615"},
+ {file = "kiwisolver-1.5.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:1d49a49ac4cbfb7c1375301cd1ec90169dfeae55ff84710d782260ce77a75a02"},
+ {file = "kiwisolver-1.5.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0cbe94b69b819209a62cb27bdfa5dc2a8977d8de2f89dfd97ba4f53ed3af754e"},
+ {file = "kiwisolver-1.5.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:80aa065ffd378ff784822a6d7c3212f2d5f5e9c3589614b5c228b311fd3063ac"},
+ {file = "kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e7f886f47ab881692f278ae901039a234e4025a68e6dfab514263a0b1c4ae05"},
+ {file = "kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5060731cc3ed12ca3a8b57acd4aeca5bbc2f49216dd0bec1650a1acd89486bcd"},
+ {file = "kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7a4aa69609f40fce3cbc3f87b2061f042eee32f94b8f11db707b66a26461591a"},
+ {file = "kiwisolver-1.5.0-cp314-cp314-manylinux_2_39_riscv64.whl", hash = "sha256:d168fda2dbff7b9b5f38e693182d792a938c31db4dac3a80a4888de603c99554"},
+ {file = "kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:413b820229730d358efd838ecbab79902fe97094565fdc80ddb6b0a18c18a581"},
+ {file = "kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:5124d1ea754509b09e53738ec185584cc609aae4a3b510aaf4ed6aa047ef9303"},
+ {file = "kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e4415a8db000bf49a6dd1c478bf70062eaacff0f462b92b0ba68791a905861f9"},
+ {file = "kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d618fd27420381a4f6044faa71f46d8bfd911bd077c555f7138ed88729bfbe79"},
+ {file = "kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5092eb5b1172947f57d6ea7d89b2f29650414e4293c47707eb499ec07a0ac796"},
+ {file = "kiwisolver-1.5.0-cp314-cp314-win_amd64.whl", hash = "sha256:d76e2d8c75051d58177e762164d2e9ab92886534e3a12e795f103524f221dd8e"},
+ {file = "kiwisolver-1.5.0-cp314-cp314-win_arm64.whl", hash = "sha256:fa6248cd194edff41d7ea9425ced8ca3a6f838bfb295f6f1d6e6bb694a8518df"},
+ {file = "kiwisolver-1.5.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:d1ffeb80b5676463d7a7d56acbe8e37a20ce725570e09549fe738e02ca6b7e1e"},
+ {file = "kiwisolver-1.5.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:bc4d8e252f532ab46a1de9349e2d27b91fce46736a9eedaa37beaca66f574ed4"},
+ {file = "kiwisolver-1.5.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6783e069732715ad0c3ce96dbf21dbc2235ab0593f2baf6338101f70371f4028"},
+ {file = "kiwisolver-1.5.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e7c4c09a490dc4d4a7f8cbee56c606a320f9dc28cf92a7157a39d1ce7676a657"},
+ {file = "kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2a075bd7bd19c70cf67c8badfa36cf7c5d8de3c9ddb8420c51e10d9c50e94920"},
+ {file = "kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bdd3e53429ff02aa319ba59dfe4ceeec345bf46cf180ec2cf6fd5b942e7975e9"},
+ {file = "kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cdcb35dc9d807259c981a85531048ede628eabcffb3239adf3d17463518992d"},
+ {file = "kiwisolver-1.5.0-cp314-cp314t-manylinux_2_39_riscv64.whl", hash = "sha256:70d593af6a6ca332d1df73d519fddb5148edb15cd90d5f0155e3746a6d4fcc65"},
+ {file = "kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:377815a8616074cabbf3f53354e1d040c35815a134e01d7614b7692e4bf8acfa"},
+ {file = "kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0255a027391d52944eae1dbb5d4cc5903f57092f3674e8e544cdd2622826b3f0"},
+ {file = "kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:012b1eb16e28718fa782b5e61dc6f2da1f0792ca73bd05d54de6cb9561665fc9"},
+ {file = "kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0e3aafb33aed7479377e5e9a82e9d4bf87063741fc99fc7ae48b0f16e32bdd6f"},
+ {file = "kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e7a116ae737f0000343218c4edf5bd45893bfeaff0993c0b215d7124c9f77646"},
+ {file = "kiwisolver-1.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:1dd9b0b119a350976a6d781e7278ec7aca0b201e1a9e2d23d9804afecb6ca681"},
+ {file = "kiwisolver-1.5.0-cp314-cp314t-win_arm64.whl", hash = "sha256:58f812017cd2985c21fbffb4864d59174d4903dd66fa23815e74bbc7a0e2dd57"},
+ {file = "kiwisolver-1.5.0-graalpy312-graalpy250_312_native-macosx_10_13_x86_64.whl", hash = "sha256:5ae8e62c147495b01a0f4765c878e9bfdf843412446a247e28df59936e99e797"},
+ {file = "kiwisolver-1.5.0-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:f6764a4ccab3078db14a632420930f6186058750df066b8ea2a7106df91d3203"},
+ {file = "kiwisolver-1.5.0-graalpy312-graalpy250_312_native-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c31c13da98624f957b0fb1b5bae5383b2333c2c3f6793d9825dd5ce79b525cb7"},
+ {file = "kiwisolver-1.5.0-graalpy312-graalpy250_312_native-win_amd64.whl", hash = "sha256:1f1489f769582498610e015a8ef2d36f28f505ab3096d0e16b4858a9ec214f57"},
+ {file = "kiwisolver-1.5.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:295d9ffe712caa9f8a3081de8d32fc60191b4b51c76f02f951fd8407253528f4"},
+ {file = "kiwisolver-1.5.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:51e8c4084897de9f05898c2c2a39af6318044ae969d46ff7a34ed3f96274adca"},
+ {file = "kiwisolver-1.5.0-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b83af57bdddef03c01a9138034c6ff03181a3028d9a1003b301eb1a55e161a3f"},
+ {file = "kiwisolver-1.5.0-pp310-pypy310_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf4679a3d71012a7c2bf360e5cd878fbd5e4fcac0896b56393dec239d81529ed"},
+ {file = "kiwisolver-1.5.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:41024ed50e44ab1a60d3fe0a9d15a4ccc9f5f2b1d814ff283c8d01134d5b81bc"},
+ {file = "kiwisolver-1.5.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ec4c85dc4b687c7f7f15f553ff26a98bfe8c58f5f7f0ac8905f0ba4c7be60232"},
+ {file = "kiwisolver-1.5.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:12e91c215a96e39f57989c8912ae761286ac5a9584d04030ceb3368a357f017a"},
+ {file = "kiwisolver-1.5.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:be4a51a55833dc29ab5d7503e7bcb3b3af3402d266018137127450005cdfe737"},
+ {file = "kiwisolver-1.5.0-pp311-pypy311_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:daae526907e262de627d8f70058a0f64acc9e2641c164c99c8f594b34a799a16"},
+ {file = "kiwisolver-1.5.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:59cd8683f575d96df5bb48f6add94afc055012c29e28124fcae2b63661b9efb1"},
+ {file = "kiwisolver-1.5.0.tar.gz", hash = "sha256:d4193f3d9dc3f6f79aaed0e5637f45d98850ebf01f7ca20e69457f3e8946b66a"},
+]
+
+[[package]]
+name = "markdown-it-py"
+version = "4.2.0"
+description = "Python port of markdown-it. Markdown parsing, done right!"
+optional = false
+python-versions = ">=3.10"
files = [
- {file = "jsonrpcclient-4.0.3-py3-none-any.whl", hash = "sha256:3cbb9e27e1be29821becf135ea183144a836215422727e1ffe5056a49a670f0d"},
+ {file = "markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a"},
+ {file = "markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49"},
]
+[package.dependencies]
+mdurl = ">=0.1,<1.0"
+
[package.extras]
-qa = ["pytest", "pytest-cov", "tox"]
+benchmarking = ["psutil", "pytest", "pytest-benchmark"]
+compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "markdown-it-pyrs", "mistletoe (>=1.0,<2.0)", "mistune (>=3.0,<4.0)", "panflute (>=2.3,<3.0)"]
+linkify = ["linkify-it-py (>=1,<3)"]
+plugins = ["mdit-py-plugins (>=0.5.0)"]
+profiling = ["gprof2dot"]
+rtd = ["ipykernel", "jupyter_sphinx", "mdit-py-plugins (>=0.5.0)", "myst-parser", "pyyaml", "sphinx", "sphinx-book-theme (>=1.0,<2.0)", "sphinx-copybutton", "sphinx-design"]
+testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions", "pytest-timeout", "requests"]
[[package]]
-name = "multidict"
-version = "6.0.5"
-description = "multidict implementation"
+name = "matplotlib"
+version = "3.10.9"
+description = "Python plotting package"
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.10"
files = [
- {file = "multidict-6.0.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:228b644ae063c10e7f324ab1ab6b548bdf6f8b47f3ec234fef1093bc2735e5f9"},
- {file = "multidict-6.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:896ebdcf62683551312c30e20614305f53125750803b614e9e6ce74a96232604"},
- {file = "multidict-6.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:411bf8515f3be9813d06004cac41ccf7d1cd46dfe233705933dd163b60e37600"},
- {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d147090048129ce3c453f0292e7697d333db95e52616b3793922945804a433c"},
- {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:215ed703caf15f578dca76ee6f6b21b7603791ae090fbf1ef9d865571039ade5"},
- {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c6390cf87ff6234643428991b7359b5f59cc15155695deb4eda5c777d2b880f"},
- {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fd81c4ebdb4f214161be351eb5bcf385426bf023041da2fd9e60681f3cebae"},
- {file = "multidict-6.0.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3cc2ad10255f903656017363cd59436f2111443a76f996584d1077e43ee51182"},
- {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6939c95381e003f54cd4c5516740faba40cf5ad3eeff460c3ad1d3e0ea2549bf"},
- {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:220dd781e3f7af2c2c1053da9fa96d9cf3072ca58f057f4c5adaaa1cab8fc442"},
- {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:766c8f7511df26d9f11cd3a8be623e59cca73d44643abab3f8c8c07620524e4a"},
- {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:fe5d7785250541f7f5019ab9cba2c71169dc7d74d0f45253f8313f436458a4ef"},
- {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c1c1496e73051918fcd4f58ff2e0f2f3066d1c76a0c6aeffd9b45d53243702cc"},
- {file = "multidict-6.0.5-cp310-cp310-win32.whl", hash = "sha256:7afcdd1fc07befad18ec4523a782cde4e93e0a2bf71239894b8d61ee578c1319"},
- {file = "multidict-6.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:99f60d34c048c5c2fabc766108c103612344c46e35d4ed9ae0673d33c8fb26e8"},
- {file = "multidict-6.0.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f285e862d2f153a70586579c15c44656f888806ed0e5b56b64489afe4a2dbfba"},
- {file = "multidict-6.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:53689bb4e102200a4fafa9de9c7c3c212ab40a7ab2c8e474491914d2305f187e"},
- {file = "multidict-6.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:612d1156111ae11d14afaf3a0669ebf6c170dbb735e510a7438ffe2369a847fd"},
- {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7be7047bd08accdb7487737631d25735c9a04327911de89ff1b26b81745bd4e3"},
- {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de170c7b4fe6859beb8926e84f7d7d6c693dfe8e27372ce3b76f01c46e489fcf"},
- {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04bde7a7b3de05732a4eb39c94574db1ec99abb56162d6c520ad26f83267de29"},
- {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85f67aed7bb647f93e7520633d8f51d3cbc6ab96957c71272b286b2f30dc70ed"},
- {file = "multidict-6.0.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425bf820055005bfc8aa9a0b99ccb52cc2f4070153e34b701acc98d201693733"},
- {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d3eb1ceec286eba8220c26f3b0096cf189aea7057b6e7b7a2e60ed36b373b77f"},
- {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7901c05ead4b3fb75113fb1dd33eb1253c6d3ee37ce93305acd9d38e0b5f21a4"},
- {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e0e79d91e71b9867c73323a3444724d496c037e578a0e1755ae159ba14f4f3d1"},
- {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:29bfeb0dff5cb5fdab2023a7a9947b3b4af63e9c47cae2a10ad58394b517fddc"},
- {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e030047e85cbcedbfc073f71836d62dd5dadfbe7531cae27789ff66bc551bd5e"},
- {file = "multidict-6.0.5-cp311-cp311-win32.whl", hash = "sha256:2f4848aa3baa109e6ab81fe2006c77ed4d3cd1e0ac2c1fbddb7b1277c168788c"},
- {file = "multidict-6.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:2faa5ae9376faba05f630d7e5e6be05be22913782b927b19d12b8145968a85ea"},
- {file = "multidict-6.0.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:51d035609b86722963404f711db441cf7134f1889107fb171a970c9701f92e1e"},
- {file = "multidict-6.0.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cbebcd5bcaf1eaf302617c114aa67569dd3f090dd0ce8ba9e35e9985b41ac35b"},
- {file = "multidict-6.0.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2ffc42c922dbfddb4a4c3b438eb056828719f07608af27d163191cb3e3aa6cc5"},
- {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ceb3b7e6a0135e092de86110c5a74e46bda4bd4fbfeeb3a3bcec79c0f861e450"},
- {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79660376075cfd4b2c80f295528aa6beb2058fd289f4c9252f986751a4cd0496"},
- {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4428b29611e989719874670fd152b6625500ad6c686d464e99f5aaeeaca175a"},
- {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d84a5c3a5f7ce6db1f999fb9438f686bc2e09d38143f2d93d8406ed2dd6b9226"},
- {file = "multidict-6.0.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76c0de87358b192de7ea9649beb392f107dcad9ad27276324c24c91774ca5271"},
- {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:79a6d2ba910adb2cbafc95dad936f8b9386e77c84c35bc0add315b856d7c3abb"},
- {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:92d16a3e275e38293623ebf639c471d3e03bb20b8ebb845237e0d3664914caef"},
- {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:fb616be3538599e797a2017cccca78e354c767165e8858ab5116813146041a24"},
- {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:14c2976aa9038c2629efa2c148022ed5eb4cb939e15ec7aace7ca932f48f9ba6"},
- {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:435a0984199d81ca178b9ae2c26ec3d49692d20ee29bc4c11a2a8d4514c67eda"},
- {file = "multidict-6.0.5-cp312-cp312-win32.whl", hash = "sha256:9fe7b0653ba3d9d65cbe7698cca585bf0f8c83dbbcc710db9c90f478e175f2d5"},
- {file = "multidict-6.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:01265f5e40f5a17f8241d52656ed27192be03bfa8764d88e8220141d1e4b3556"},
- {file = "multidict-6.0.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:19fe01cea168585ba0f678cad6f58133db2aa14eccaf22f88e4a6dccadfad8b3"},
- {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6bf7a982604375a8d49b6cc1b781c1747f243d91b81035a9b43a2126c04766f5"},
- {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:107c0cdefe028703fb5dafe640a409cb146d44a6ae201e55b35a4af8e95457dd"},
- {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:403c0911cd5d5791605808b942c88a8155c2592e05332d2bf78f18697a5fa15e"},
- {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aeaf541ddbad8311a87dd695ed9642401131ea39ad7bc8cf3ef3967fd093b626"},
- {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e4972624066095e52b569e02b5ca97dbd7a7ddd4294bf4e7247d52635630dd83"},
- {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d946b0a9eb8aaa590df1fe082cee553ceab173e6cb5b03239716338629c50c7a"},
- {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b55358304d7a73d7bdf5de62494aaf70bd33015831ffd98bc498b433dfe5b10c"},
- {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:a3145cb08d8625b2d3fee1b2d596a8766352979c9bffe5d7833e0503d0f0b5e5"},
- {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d65f25da8e248202bd47445cec78e0025c0fe7582b23ec69c3b27a640dd7a8e3"},
- {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c9bf56195c6bbd293340ea82eafd0071cb3d450c703d2c93afb89f93b8386ccc"},
- {file = "multidict-6.0.5-cp37-cp37m-win32.whl", hash = "sha256:69db76c09796b313331bb7048229e3bee7928eb62bab5e071e9f7fcc4879caee"},
- {file = "multidict-6.0.5-cp37-cp37m-win_amd64.whl", hash = "sha256:fce28b3c8a81b6b36dfac9feb1de115bab619b3c13905b419ec71d03a3fc1423"},
- {file = "multidict-6.0.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:76f067f5121dcecf0d63a67f29080b26c43c71a98b10c701b0677e4a065fbd54"},
- {file = "multidict-6.0.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b82cc8ace10ab5bd93235dfaab2021c70637005e1ac787031f4d1da63d493c1d"},
- {file = "multidict-6.0.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5cb241881eefd96b46f89b1a056187ea8e9ba14ab88ba632e68d7a2ecb7aadf7"},
- {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8e94e6912639a02ce173341ff62cc1201232ab86b8a8fcc05572741a5dc7d93"},
- {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09a892e4a9fb47331da06948690ae38eaa2426de97b4ccbfafbdcbe5c8f37ff8"},
- {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55205d03e8a598cfc688c71ca8ea5f66447164efff8869517f175ea632c7cb7b"},
- {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37b15024f864916b4951adb95d3a80c9431299080341ab9544ed148091b53f50"},
- {file = "multidict-6.0.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2a1dee728b52b33eebff5072817176c172050d44d67befd681609b4746e1c2e"},
- {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:edd08e6f2f1a390bf137080507e44ccc086353c8e98c657e666c017718561b89"},
- {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:60d698e8179a42ec85172d12f50b1668254628425a6bd611aba022257cac1386"},
- {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:3d25f19500588cbc47dc19081d78131c32637c25804df8414463ec908631e453"},
- {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:4cc0ef8b962ac7a5e62b9e826bd0cd5040e7d401bc45a6835910ed699037a461"},
- {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:eca2e9d0cc5a889850e9bbd68e98314ada174ff6ccd1129500103df7a94a7a44"},
- {file = "multidict-6.0.5-cp38-cp38-win32.whl", hash = "sha256:4a6a4f196f08c58c59e0b8ef8ec441d12aee4125a7d4f4fef000ccb22f8d7241"},
- {file = "multidict-6.0.5-cp38-cp38-win_amd64.whl", hash = "sha256:0275e35209c27a3f7951e1ce7aaf93ce0d163b28948444bec61dd7badc6d3f8c"},
- {file = "multidict-6.0.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e7be68734bd8c9a513f2b0cfd508802d6609da068f40dc57d4e3494cefc92929"},
- {file = "multidict-6.0.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1d9ea7a7e779d7a3561aade7d596649fbecfa5c08a7674b11b423783217933f9"},
- {file = "multidict-6.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ea1456df2a27c73ce51120fa2f519f1bea2f4a03a917f4a43c8707cf4cbbae1a"},
- {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf590b134eb70629e350691ecca88eac3e3b8b3c86992042fb82e3cb1830d5e1"},
- {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5c0631926c4f58e9a5ccce555ad7747d9a9f8b10619621f22f9635f069f6233e"},
- {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1c6912ab9ff5f179eaf6efe7365c1f425ed690b03341911bf4939ef2f3046"},
- {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0868d64af83169e4d4152ec612637a543f7a336e4a307b119e98042e852ad9c"},
- {file = "multidict-6.0.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:141b43360bfd3bdd75f15ed811850763555a251e38b2405967f8e25fb43f7d40"},
- {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7df704ca8cf4a073334e0427ae2345323613e4df18cc224f647f251e5e75a527"},
- {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6214c5a5571802c33f80e6c84713b2c79e024995b9c5897f794b43e714daeec9"},
- {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:cd6c8fca38178e12c00418de737aef1261576bd1b6e8c6134d3e729a4e858b38"},
- {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:e02021f87a5b6932fa6ce916ca004c4d441509d33bbdbeca70d05dff5e9d2479"},
- {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ebd8d160f91a764652d3e51ce0d2956b38efe37c9231cd82cfc0bed2e40b581c"},
- {file = "multidict-6.0.5-cp39-cp39-win32.whl", hash = "sha256:04da1bb8c8dbadf2a18a452639771951c662c5ad03aefe4884775454be322c9b"},
- {file = "multidict-6.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:d6f6d4f185481c9669b9447bf9d9cf3b95a0e9df9d169bbc17e363b7d5487755"},
- {file = "multidict-6.0.5-py3-none-any.whl", hash = "sha256:0d63c74e3d7ab26de115c49bffc92cc77ed23395303d496eae515d4204a625e7"},
- {file = "multidict-6.0.5.tar.gz", hash = "sha256:f7e301075edaf50500f0b341543c41194d8df3ae5caf4702f2095f3ca73dd8da"},
+ {file = "matplotlib-3.10.9-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:77210dce9cb8153dffc967efaae990543392563d5a376d4dd8539bebcb0ed217"},
+ {file = "matplotlib-3.10.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1e7698ac9868428e84d2c967424803b2472ff7167d9d6590d4204ed775343c3b"},
+ {file = "matplotlib-3.10.9-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1aa972116abb4c9d201bf245620b433726cb6856f3bef6a78f776a00f5c92d37"},
+ {file = "matplotlib-3.10.9-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ae2f11957b27ce53497dd4d7b235c4d4f1faf383dfb39d0c5beb833bff883294"},
+ {file = "matplotlib-3.10.9-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b049278ddce116aaa1c1377ebf58adea909132dfce0281cf7e3a1ea9fc2e2c65"},
+ {file = "matplotlib-3.10.9-cp310-cp310-win_amd64.whl", hash = "sha256:82834c3c292d24d3a8aae77cd2d20019de69d692a34a970e4fdb8d33e2ea3dda"},
+ {file = "matplotlib-3.10.9-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:68cfdcede415f7c8f5577b03303dd94526cdb6d11036cecdc205e08733b2d2bb"},
+ {file = "matplotlib-3.10.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfca0129678bd56379db26c52b5d77ed7de314c047492fbdc763aa7501710cfb"},
+ {file = "matplotlib-3.10.9-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8e436d155fa8a3399dc62683f8f5d0e2e50d25d0144a73edd73f82eec8f4abfb"},
+ {file = "matplotlib-3.10.9-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:56fc0bd271b00025c6edfdc7c2dcd247372c8e1544971d62e1dc7c17367e8bf9"},
+ {file = "matplotlib-3.10.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a5a6104ed666402ba5106d7f36e0e0cdca4e8d7fa4d39708ca88019e2835a2eb"},
+ {file = "matplotlib-3.10.9-cp311-cp311-win_amd64.whl", hash = "sha256:d730e984eddf56974c3e72b6129c7ca462ac38dc624338f4b0b23eb23ecba00f"},
+ {file = "matplotlib-3.10.9-cp311-cp311-win_arm64.whl", hash = "sha256:51bf0ddbdc598e060d46c16b5590708f81a1624cefbaaf62f6a81bf9285b8c80"},
+ {file = "matplotlib-3.10.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f0c3c28d9fbcc1fe7a03be236d73430cf6409c41fb2383a7ac52fe932b072cb1"},
+ {file = "matplotlib-3.10.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:41cb28c2bd769aa3e98322c6ab09854cbcc52ab69d2759d681bba3e327b2b320"},
+ {file = "matplotlib-3.10.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ae20801130378b82d647ff5047c07316295b68dc054ca6b3c13519d0ea624285"},
+ {file = "matplotlib-3.10.9-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6c63ebcd8b4b169eb2f5c200552ae6b8be8999a005b6b507ed76fb8d7d674fe2"},
+ {file = "matplotlib-3.10.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d75d11c949914165976c621b2324f9ef162af7ebf4b057ddf95dd1dba7e5edcf"},
+ {file = "matplotlib-3.10.9-cp312-cp312-win_amd64.whl", hash = "sha256:d091f9d758b34aaaaa6331d13574bf01891d903b3dec59bfff458ef7551de5d6"},
+ {file = "matplotlib-3.10.9-cp312-cp312-win_arm64.whl", hash = "sha256:10cc5ce06d10231c36f40e875f3c7e8050362a4ee8f0ee5d29a6b3277d57bb42"},
+ {file = "matplotlib-3.10.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b580440f1ff81a0e34122051a3dfabb7e4b7f9e380629929bde0eff9af72165f"},
+ {file = "matplotlib-3.10.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b1b745c489cd1a77a0dc1120a05dc87af9798faebc913601feb8c73d89bf2d1e"},
+ {file = "matplotlib-3.10.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8f3bcac1ca5ed000a6f4337d47ba67dfddf37ed6a46c15fd7f014997f7bf865f"},
+ {file = "matplotlib-3.10.9-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7a8d66a55def891c33147ba3ba9bfcabf0b526a43764c818acbb4525e5ed0838"},
+ {file = "matplotlib-3.10.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d843374407c4017a6403b59c6c81606773d136f3259d5b6da3131bc814542cc2"},
+ {file = "matplotlib-3.10.9-cp313-cp313-win_amd64.whl", hash = "sha256:f4399f64b3e94cd500195490972ae1ee81170df1636fa15364d157d5bdd7b921"},
+ {file = "matplotlib-3.10.9-cp313-cp313-win_arm64.whl", hash = "sha256:ba7b3b8ef09eab7df0e86e9ae086faa433efbfbdb46afcb3aa16aabf779469a8"},
+ {file = "matplotlib-3.10.9-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:09218df8a93712bd6ea133e83a153c755448cf7868316c531cffcc43f69d1cc9"},
+ {file = "matplotlib-3.10.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:82368699727bfb7b0182e1aa13082e3c08e092fa1a25d3e1fd92405bff96f6d4"},
+ {file = "matplotlib-3.10.9-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3225f4e1edcb8c86c884ddf79ebe20ecd0a67d30188f279897554ccd8fded4dc"},
+ {file = "matplotlib-3.10.9-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:de2445a0c6690d21b7eb6ce071cebad6d40a2e9bdf10d039074a96ba19797b99"},
+ {file = "matplotlib-3.10.9-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:b2b9516251cb89ff618d757daec0e2ed1bf21248013844a853d87ef85ab3081d"},
+ {file = "matplotlib-3.10.9-cp313-cp313t-win_amd64.whl", hash = "sha256:e9fae004b941b23ff2edcf1567a857ed77bafc8086ffa258190462328434faf8"},
+ {file = "matplotlib-3.10.9-cp313-cp313t-win_arm64.whl", hash = "sha256:6b63d9c7c769b88ab81e10dc86e4e0607cf56817b9f9e6cf24b2a5f1693b8e38"},
+ {file = "matplotlib-3.10.9-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:172db52c9e683f5d12eaf57f0f54834190e12581fe1cc2a19595a8f5acb4e77d"},
+ {file = "matplotlib-3.10.9-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:97e35e8d39ccc85859095e01a53847432ba9a53ddf7986f7a54a11b73d0e143f"},
+ {file = "matplotlib-3.10.9-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aba1615dabe83188e19d4f75a253c6a08423e04c1425e64039f800050a69de6b"},
+ {file = "matplotlib-3.10.9-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34cf8167e023ad956c15f36302911d5406bd99a9862c1a8499ea6f7c0e015dc2"},
+ {file = "matplotlib-3.10.9-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:59476c6d29d612b8e9bb6ce8c5b631be6ba8f9e3a2421f22a02b192c7dd28716"},
+ {file = "matplotlib-3.10.9-cp314-cp314-win_amd64.whl", hash = "sha256:336b9acc64d309063126edcdaca00db9373af3c476bb94388fe9c5a53ad13e6f"},
+ {file = "matplotlib-3.10.9-cp314-cp314-win_arm64.whl", hash = "sha256:2dc9477819ffd78ad12a20df1d9d6a6bd4fec6aaa9072681465fddca052f1456"},
+ {file = "matplotlib-3.10.9-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:da4e09638420548f31c354032a6250e473c68e5a4e96899b4844cf39ddea23fe"},
+ {file = "matplotlib-3.10.9-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:345f6f68ecc8da0ca56fad2ea08fde1a115eda530079eca185d50a7bc3e146c6"},
+ {file = "matplotlib-3.10.9-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4edcfbd8565339aa62f1cd4012f7180926fdbe71850f7b0d3c379c175cd6b66c"},
+ {file = "matplotlib-3.10.9-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6be157fe17fc37cb95ac1d7374cf717ce9259616edec911a78d9d26dae8522d4"},
+ {file = "matplotlib-3.10.9-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:4e42042d54db34fda4e95a7bd3e5789c2a995d2dad3eb8850232ee534092fbbf"},
+ {file = "matplotlib-3.10.9-cp314-cp314t-win_amd64.whl", hash = "sha256:c27df8b3848f32a83d1767566595e43cfaa4460380974da06f4279a7ec143c39"},
+ {file = "matplotlib-3.10.9-cp314-cp314t-win_arm64.whl", hash = "sha256:a49f1eadc84ca85fd72fa4e89e70e61bf86452df6f971af04b12c60761a0772c"},
+ {file = "matplotlib-3.10.9-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1872fb212a05b729e649754a72d5da61d03e0554d76e80303b6f83d1d2c0552b"},
+ {file = "matplotlib-3.10.9-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:985f2238880e2e69093f588f5fe2e46771747febf0649f3cf7f7b7480875317f"},
+ {file = "matplotlib-3.10.9-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6640f75af2c6148293caa0a2b39dd806a492dd66c8a8b04035813e33d0fd2585"},
+ {file = "matplotlib-3.10.9-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:42fb814efabe95c06c1994d8ab5a8385f43a249e23badd3ba931d4308e5bca20"},
+ {file = "matplotlib-3.10.9-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:f76e640a5268850bfda54b5131b1b1941cc685e42c5fa98ed9f2d64038308cba"},
+ {file = "matplotlib-3.10.9-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3fc0364dfbe1d07f6d15c5ebd0c5bf89e126916e5a8667dd4a7a6e84c36653d4"},
+ {file = "matplotlib-3.10.9.tar.gz", hash = "sha256:fd66508e8c6877d98e586654b608a0456db8d7e8a546eb1e2600efd957302358"},
]
+[package.dependencies]
+contourpy = ">=1.0.1"
+cycler = ">=0.10"
+fonttools = ">=4.22.0"
+kiwisolver = ">=1.3.1"
+numpy = ">=1.23"
+packaging = ">=20.0"
+pillow = ">=8"
+pyparsing = ">=3"
+python-dateutil = ">=2.7"
+
+[package.extras]
+dev = ["meson-python (>=0.13.1,<0.17.0)", "pybind11 (>=2.13.2,!=2.13.3)", "setuptools (>=64)", "setuptools_scm (>=7,<10)"]
+
[[package]]
-name = "mypy-extensions"
-version = "1.0.0"
-description = "Type system extensions for programs checked with the mypy type checker."
+name = "mdurl"
+version = "0.1.2"
+description = "Markdown URL utilities"
optional = false
-python-versions = ">=3.5"
+python-versions = ">=3.7"
files = [
- {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"},
- {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
+ {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"},
+ {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"},
]
[[package]]
-name = "packaging"
-version = "24.0"
-description = "Core utilities for Python packages"
+name = "numpy"
+version = "2.2.6"
+description = "Fundamental package for array computing in Python"
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.10"
files = [
- {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"},
- {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"},
+ {file = "numpy-2.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b412caa66f72040e6d268491a59f2c43bf03eb6c96dd8f0307829feb7fa2b6fb"},
+ {file = "numpy-2.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e41fd67c52b86603a91c1a505ebaef50b3314de0213461c7a6e99c9a3beff90"},
+ {file = "numpy-2.2.6-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:37e990a01ae6ec7fe7fa1c26c55ecb672dd98b19c3d0e1d1f326fa13cb38d163"},
+ {file = "numpy-2.2.6-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:5a6429d4be8ca66d889b7cf70f536a397dc45ba6faeb5f8c5427935d9592e9cf"},
+ {file = "numpy-2.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efd28d4e9cd7d7a8d39074a4d44c63eda73401580c5c76acda2ce969e0a38e83"},
+ {file = "numpy-2.2.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc7b73d02efb0e18c000e9ad8b83480dfcd5dfd11065997ed4c6747470ae8915"},
+ {file = "numpy-2.2.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:74d4531beb257d2c3f4b261bfb0fc09e0f9ebb8842d82a7b4209415896adc680"},
+ {file = "numpy-2.2.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8fc377d995680230e83241d8a96def29f204b5782f371c532579b4f20607a289"},
+ {file = "numpy-2.2.6-cp310-cp310-win32.whl", hash = "sha256:b093dd74e50a8cba3e873868d9e93a85b78e0daf2e98c6797566ad8044e8363d"},
+ {file = "numpy-2.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:f0fd6321b839904e15c46e0d257fdd101dd7f530fe03fd6359c1ea63738703f3"},
+ {file = "numpy-2.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f9f1adb22318e121c5c69a09142811a201ef17ab257a1e66ca3025065b7f53ae"},
+ {file = "numpy-2.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c820a93b0255bc360f53eca31a0e676fd1101f673dda8da93454a12e23fc5f7a"},
+ {file = "numpy-2.2.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3d70692235e759f260c3d837193090014aebdf026dfd167834bcba43e30c2a42"},
+ {file = "numpy-2.2.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:481b49095335f8eed42e39e8041327c05b0f6f4780488f61286ed3c01368d491"},
+ {file = "numpy-2.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b64d8d4d17135e00c8e346e0a738deb17e754230d7e0810ac5012750bbd85a5a"},
+ {file = "numpy-2.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba10f8411898fc418a521833e014a77d3ca01c15b0c6cdcce6a0d2897e6dbbdf"},
+ {file = "numpy-2.2.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bd48227a919f1bafbdda0583705e547892342c26fb127219d60a5c36882609d1"},
+ {file = "numpy-2.2.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9551a499bf125c1d4f9e250377c1ee2eddd02e01eac6644c080162c0c51778ab"},
+ {file = "numpy-2.2.6-cp311-cp311-win32.whl", hash = "sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47"},
+ {file = "numpy-2.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303"},
+ {file = "numpy-2.2.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41c5a21f4a04fa86436124d388f6ed60a9343a6f767fced1a8a71c3fbca038ff"},
+ {file = "numpy-2.2.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de749064336d37e340f640b05f24e9e3dd678c57318c7289d222a8a2f543e90c"},
+ {file = "numpy-2.2.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:894b3a42502226a1cac872f840030665f33326fc3dac8e57c607905773cdcde3"},
+ {file = "numpy-2.2.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:71594f7c51a18e728451bb50cc60a3ce4e6538822731b2933209a1f3614e9282"},
+ {file = "numpy-2.2.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2618db89be1b4e05f7a1a847a9c1c0abd63e63a1607d892dd54668dd92faf87"},
+ {file = "numpy-2.2.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd83c01228a688733f1ded5201c678f0c53ecc1006ffbc404db9f7a899ac6249"},
+ {file = "numpy-2.2.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:37c0ca431f82cd5fa716eca9506aefcabc247fb27ba69c5062a6d3ade8cf8f49"},
+ {file = "numpy-2.2.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fe27749d33bb772c80dcd84ae7e8df2adc920ae8297400dabec45f0dedb3f6de"},
+ {file = "numpy-2.2.6-cp312-cp312-win32.whl", hash = "sha256:4eeaae00d789f66c7a25ac5f34b71a7035bb474e679f410e5e1a94deb24cf2d4"},
+ {file = "numpy-2.2.6-cp312-cp312-win_amd64.whl", hash = "sha256:c1f9540be57940698ed329904db803cf7a402f3fc200bfe599334c9bd84a40b2"},
+ {file = "numpy-2.2.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0811bb762109d9708cca4d0b13c4f67146e3c3b7cf8d34018c722adb2d957c84"},
+ {file = "numpy-2.2.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:287cc3162b6f01463ccd86be154f284d0893d2b3ed7292439ea97eafa8170e0b"},
+ {file = "numpy-2.2.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f1372f041402e37e5e633e586f62aa53de2eac8d98cbfb822806ce4bbefcb74d"},
+ {file = "numpy-2.2.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:55a4d33fa519660d69614a9fad433be87e5252f4b03850642f88993f7b2ca566"},
+ {file = "numpy-2.2.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f92729c95468a2f4f15e9bb94c432a9229d0d50de67304399627a943201baa2f"},
+ {file = "numpy-2.2.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f"},
+ {file = "numpy-2.2.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e3143e4451880bed956e706a3220b4e5cf6172ef05fcc397f6f36a550b1dd868"},
+ {file = "numpy-2.2.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4f13750ce79751586ae2eb824ba7e1e8dba64784086c98cdbbcc6a42112ce0d"},
+ {file = "numpy-2.2.6-cp313-cp313-win32.whl", hash = "sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd"},
+ {file = "numpy-2.2.6-cp313-cp313-win_amd64.whl", hash = "sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c"},
+ {file = "numpy-2.2.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0bca768cd85ae743b2affdc762d617eddf3bcf8724435498a1e80132d04879e6"},
+ {file = "numpy-2.2.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fc0c5673685c508a142ca65209b4e79ed6740a4ed6b2267dbba90f34b0b3cfda"},
+ {file = "numpy-2.2.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:5bd4fc3ac8926b3819797a7c0e2631eb889b4118a9898c84f585a54d475b7e40"},
+ {file = "numpy-2.2.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8"},
+ {file = "numpy-2.2.6-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1dda9c7e08dc141e0247a5b8f49cf05984955246a327d4c48bda16821947b2f"},
+ {file = "numpy-2.2.6-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f447e6acb680fd307f40d3da4852208af94afdfab89cf850986c3ca00562f4fa"},
+ {file = "numpy-2.2.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:389d771b1623ec92636b0786bc4ae56abafad4a4c513d36a55dce14bd9ce8571"},
+ {file = "numpy-2.2.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8e9ace4a37db23421249ed236fdcdd457d671e25146786dfc96835cd951aa7c1"},
+ {file = "numpy-2.2.6-cp313-cp313t-win32.whl", hash = "sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff"},
+ {file = "numpy-2.2.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06"},
+ {file = "numpy-2.2.6-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0b605b275d7bd0c640cad4e5d30fa701a8d59302e127e5f79138ad62762c3e3d"},
+ {file = "numpy-2.2.6-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:7befc596a7dc9da8a337f79802ee8adb30a552a94f792b9c9d18c840055907db"},
+ {file = "numpy-2.2.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce47521a4754c8f4593837384bd3424880629f718d87c5d44f8ed763edd63543"},
+ {file = "numpy-2.2.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d042d24c90c41b54fd506da306759e06e568864df8ec17ccc17e9e884634fd00"},
+ {file = "numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd"},
]
[[package]]
-name = "pathspec"
-version = "0.12.1"
-description = "Utility library for gitignore style pattern matching of file paths."
+name = "packaging"
+version = "26.2"
+description = "Core utilities for Python packages"
optional = false
python-versions = ">=3.8"
files = [
- {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"},
- {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"},
+ {file = "packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e"},
+ {file = "packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661"},
]
[[package]]
-name = "platformdirs"
-version = "4.2.0"
-description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
+name = "pillow"
+version = "12.2.0"
+description = "Python Imaging Library (fork)"
optional = false
-python-versions = ">=3.8"
+python-versions = ">=3.10"
files = [
- {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"},
- {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"},
+ {file = "pillow-12.2.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:a4e8f36e677d3336f35089648c8955c51c6d386a13cf6ee9c189c5f5bd713a9f"},
+ {file = "pillow-12.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2e589959f10d9824d39b350472b92f0ce3b443c0a3442ebf41c40cb8361c5b97"},
+ {file = "pillow-12.2.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a52edc8bfff4429aaabdf4d9ee0daadbbf8562364f940937b941f87a4290f5ff"},
+ {file = "pillow-12.2.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:975385f4776fafde056abb318f612ef6285b10a1f12b8570f3647ad0d74b48ec"},
+ {file = "pillow-12.2.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bd9c0c7a0c681a347b3194c500cb1e6ca9cab053ea4d82a5cf45b6b754560136"},
+ {file = "pillow-12.2.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:88d387ff40b3ff7c274947ed3125dedf5262ec6919d83946753b5f3d7c67ea4c"},
+ {file = "pillow-12.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:51c4167c34b0d8ba05b547a3bb23578d0ba17b80a5593f93bd8ecb123dd336a3"},
+ {file = "pillow-12.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:34c0d99ecccea270c04882cb3b86e7b57296079c9a4aff88cb3b33563d95afaa"},
+ {file = "pillow-12.2.0-cp310-cp310-win32.whl", hash = "sha256:b85f66ae9eb53e860a873b858b789217ba505e5e405a24b85c0464822fe88032"},
+ {file = "pillow-12.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:673aa32138f3e7531ccdbca7b3901dba9b70940a19ccecc6a37c77d5fdeb05b5"},
+ {file = "pillow-12.2.0-cp310-cp310-win_arm64.whl", hash = "sha256:3e080565d8d7c671db5802eedfb438e5565ffa40115216eabb8cd52d0ecce024"},
+ {file = "pillow-12.2.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:8be29e59487a79f173507c30ddf57e733a357f67881430449bb32614075a40ab"},
+ {file = "pillow-12.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:71cde9a1e1551df7d34a25462fc60325e8a11a82cc2e2f54578e5e9a1e153d65"},
+ {file = "pillow-12.2.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f490f9368b6fc026f021db16d7ec2fbf7d89e2edb42e8ec09d2c60505f5729c7"},
+ {file = "pillow-12.2.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8bd7903a5f2a4545f6fd5935c90058b89d30045568985a71c79f5fd6edf9b91e"},
+ {file = "pillow-12.2.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3997232e10d2920a68d25191392e3a4487d8183039e1c74c2297f00ed1c50705"},
+ {file = "pillow-12.2.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e74473c875d78b8e9d5da2a70f7099549f9eb37ded4e2f6a463e60125bccd176"},
+ {file = "pillow-12.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:56a3f9c60a13133a98ecff6197af34d7824de9b7b38c3654861a725c970c197b"},
+ {file = "pillow-12.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:90e6f81de50ad6b534cab6e5aef77ff6e37722b2f5d908686f4a5c9eba17a909"},
+ {file = "pillow-12.2.0-cp311-cp311-win32.whl", hash = "sha256:8c984051042858021a54926eb597d6ee3012393ce9c181814115df4c60b9a808"},
+ {file = "pillow-12.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e6b2a0c538fc200b38ff9eb6628228b77908c319a005815f2dde585a0664b60"},
+ {file = "pillow-12.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:9a8a34cc89c67a65ea7437ce257cea81a9dad65b29805f3ecee8c8fe8ff25ffe"},
+ {file = "pillow-12.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2d192a155bbcec180f8564f693e6fd9bccff5a7af9b32e2e4bf8c9c69dbad6b5"},
+ {file = "pillow-12.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f3f40b3c5a968281fd507d519e444c35f0ff171237f4fdde090dd60699458421"},
+ {file = "pillow-12.2.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:03e7e372d5240cc23e9f07deca4d775c0817bffc641b01e9c3af208dbd300987"},
+ {file = "pillow-12.2.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b86024e52a1b269467a802258c25521e6d742349d760728092e1bc2d135b4d76"},
+ {file = "pillow-12.2.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7371b48c4fa448d20d2714c9a1f775a81155050d383333e0a6c15b1123dda005"},
+ {file = "pillow-12.2.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:62f5409336adb0663b7caa0da5c7d9e7bdbaae9ce761d34669420c2a801b2780"},
+ {file = "pillow-12.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:01afa7cf67f74f09523699b4e88c73fb55c13346d212a59a2db1f86b0a63e8c5"},
+ {file = "pillow-12.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fc3d34d4a8fbec3e88a79b92e5465e0f9b842b628675850d860b8bd300b159f5"},
+ {file = "pillow-12.2.0-cp312-cp312-win32.whl", hash = "sha256:58f62cc0f00fd29e64b29f4fd923ffdb3859c9f9e6105bfc37ba1d08994e8940"},
+ {file = "pillow-12.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:7f84204dee22a783350679a0333981df803dac21a0190d706a50475e361c93f5"},
+ {file = "pillow-12.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:af73337013e0b3b46f175e79492d96845b16126ddf79c438d7ea7ff27783a414"},
+ {file = "pillow-12.2.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:8297651f5b5679c19968abefd6bb84d95fe30ef712eb1b2d9b2d31ca61267f4c"},
+ {file = "pillow-12.2.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:50d8520da2a6ce0af445fa6d648c4273c3eeefbc32d7ce049f22e8b5c3daecc2"},
+ {file = "pillow-12.2.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:766cef22385fa1091258ad7e6216792b156dc16d8d3fa607e7545b2b72061f1c"},
+ {file = "pillow-12.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5d2fd0fa6b5d9d1de415060363433f28da8b1526c1c129020435e186794b3795"},
+ {file = "pillow-12.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:56b25336f502b6ed02e889f4ece894a72612fe885889a6e8c4c80239ff6e5f5f"},
+ {file = "pillow-12.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f1c943e96e85df3d3478f7b691f229887e143f81fedab9b20205349ab04d73ed"},
+ {file = "pillow-12.2.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:03f6fab9219220f041c74aeaa2939ff0062bd5c364ba9ce037197f4c6d498cd9"},
+ {file = "pillow-12.2.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5cdfebd752ec52bf5bb4e35d9c64b40826bc5b40a13df7c3cda20a2c03a0f5ed"},
+ {file = "pillow-12.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eedf4b74eda2b5a4b2b2fb4c006d6295df3bf29e459e198c90ea48e130dc75c3"},
+ {file = "pillow-12.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:00a2865911330191c0b818c59103b58a5e697cae67042366970a6b6f1b20b7f9"},
+ {file = "pillow-12.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1e1757442ed87f4912397c6d35a0db6a7b52592156014706f17658ff58bbf795"},
+ {file = "pillow-12.2.0-cp313-cp313-win32.whl", hash = "sha256:144748b3af2d1b358d41286056d0003f47cb339b8c43a9ea42f5fea4d8c66b6e"},
+ {file = "pillow-12.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:390ede346628ccc626e5730107cde16c42d3836b89662a115a921f28440e6a3b"},
+ {file = "pillow-12.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:8023abc91fba39036dbce14a7d6535632f99c0b857807cbbbf21ecc9f4717f06"},
+ {file = "pillow-12.2.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:042db20a421b9bafecc4b84a8b6e444686bd9d836c7fd24542db3e7df7baad9b"},
+ {file = "pillow-12.2.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:dd025009355c926a84a612fecf58bb315a3f6814b17ead51a8e48d3823d9087f"},
+ {file = "pillow-12.2.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:88ddbc66737e277852913bd1e07c150cc7bb124539f94c4e2df5344494e0a612"},
+ {file = "pillow-12.2.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d362d1878f00c142b7e1a16e6e5e780f02be8195123f164edf7eddd911eefe7c"},
+ {file = "pillow-12.2.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2c727a6d53cb0018aadd8018c2b938376af27914a68a492f59dfcaca650d5eea"},
+ {file = "pillow-12.2.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:efd8c21c98c5cc60653bcb311bef2ce0401642b7ce9d09e03a7da87c878289d4"},
+ {file = "pillow-12.2.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9f08483a632889536b8139663db60f6724bfcb443c96f1b18855860d7d5c0fd4"},
+ {file = "pillow-12.2.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dac8d77255a37e81a2efcbd1fc05f1c15ee82200e6c240d7e127e25e365c39ea"},
+ {file = "pillow-12.2.0-cp313-cp313t-win32.whl", hash = "sha256:ee3120ae9dff32f121610bb08e4313be87e03efeadfc6c0d18f89127e24d0c24"},
+ {file = "pillow-12.2.0-cp313-cp313t-win_amd64.whl", hash = "sha256:325ca0528c6788d2a6c3d40e3568639398137346c3d6e66bb61db96b96511c98"},
+ {file = "pillow-12.2.0-cp313-cp313t-win_arm64.whl", hash = "sha256:2e5a76d03a6c6dcef67edabda7a52494afa4035021a79c8558e14af25313d453"},
+ {file = "pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:3adc9215e8be0448ed6e814966ecf3d9952f0ea40eb14e89a102b87f450660d8"},
+ {file = "pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:6a9adfc6d24b10f89588096364cc726174118c62130c817c2837c60cf08a392b"},
+ {file = "pillow-12.2.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:6a6e67ea2e6feda684ed370f9a1c52e7a243631c025ba42149a2cc5934dec295"},
+ {file = "pillow-12.2.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2bb4a8d594eacdfc59d9e5ad972aa8afdd48d584ffd5f13a937a664c3e7db0ed"},
+ {file = "pillow-12.2.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:80b2da48193b2f33ed0c32c38140f9d3186583ce7d516526d462645fd98660ae"},
+ {file = "pillow-12.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22db17c68434de69d8ecfc2fe821569195c0c373b25cccb9cbdacf2c6e53c601"},
+ {file = "pillow-12.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7b14cc0106cd9aecda615dd6903840a058b4700fcb817687d0ee4fc8b6e389be"},
+ {file = "pillow-12.2.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cbeb542b2ebc6fcdacabf8aca8c1a97c9b3ad3927d46b8723f9d4f033288a0f"},
+ {file = "pillow-12.2.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4bfd07bc812fbd20395212969e41931001fd59eb55a60658b0e5710872e95286"},
+ {file = "pillow-12.2.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9aba9a17b623ef750a4d11b742cbafffeb48a869821252b30ee21b5e91392c50"},
+ {file = "pillow-12.2.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:deede7c263feb25dba4e82ea23058a235dcc2fe1f6021025dc71f2b618e26104"},
+ {file = "pillow-12.2.0-cp314-cp314-win32.whl", hash = "sha256:632ff19b2778e43162304d50da0181ce24ac5bb8180122cbe1bf4673428328c7"},
+ {file = "pillow-12.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:4e6c62e9d237e9b65fac06857d511e90d8461a32adcc1b9065ea0c0fa3a28150"},
+ {file = "pillow-12.2.0-cp314-cp314-win_arm64.whl", hash = "sha256:b1c1fbd8a5a1af3412a0810d060a78b5136ec0836c8a4ef9aa11807f2a22f4e1"},
+ {file = "pillow-12.2.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:57850958fe9c751670e49b2cecf6294acc99e562531f4bd317fa5ddee2068463"},
+ {file = "pillow-12.2.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d5d38f1411c0ed9f97bcb49b7bd59b6b7c314e0e27420e34d99d844b9ce3b6f3"},
+ {file = "pillow-12.2.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5c0a9f29ca8e79f09de89293f82fc9b0270bb4af1d58bc98f540cc4aedf03166"},
+ {file = "pillow-12.2.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1610dd6c61621ae1cf811bef44d77e149ce3f7b95afe66a4512f8c59f25d9ebe"},
+ {file = "pillow-12.2.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a34329707af4f73cf1782a36cd2289c0368880654a2c11f027bcee9052d35dd"},
+ {file = "pillow-12.2.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e9c4f5b3c546fa3458a29ab22646c1c6c787ea8f5ef51300e5a60300736905e"},
+ {file = "pillow-12.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:fb043ee2f06b41473269765c2feae53fc2e2fbf96e5e22ca94fb5ad677856f06"},
+ {file = "pillow-12.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f278f034eb75b4e8a13a54a876cc4a5ab39173d2cdd93a638e1b467fc545ac43"},
+ {file = "pillow-12.2.0-cp314-cp314t-win32.whl", hash = "sha256:6bb77b2dcb06b20f9f4b4a8454caa581cd4dd0643a08bacf821216a16d9c8354"},
+ {file = "pillow-12.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:6562ace0d3fb5f20ed7290f1f929cae41b25ae29528f2af1722966a0a02e2aa1"},
+ {file = "pillow-12.2.0-cp314-cp314t-win_arm64.whl", hash = "sha256:aa88ccfe4e32d362816319ed727a004423aab09c5cea43c01a4b435643fa34eb"},
+ {file = "pillow-12.2.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0538bd5e05efec03ae613fd89c4ce0368ecd2ba239cc25b9f9be7ed426b0af1f"},
+ {file = "pillow-12.2.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:394167b21da716608eac917c60aa9b969421b5dcbbe02ae7f013e7b85811c69d"},
+ {file = "pillow-12.2.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5d04bfa02cc2d23b497d1e90a0f927070043f6cbf303e738300532379a4b4e0f"},
+ {file = "pillow-12.2.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0c838a5125cee37e68edec915651521191cef1e6aa336b855f495766e77a366e"},
+ {file = "pillow-12.2.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a6c9fa44005fa37a91ebfc95d081e8079757d2e904b27103f4f5fa6f0bf78c0"},
+ {file = "pillow-12.2.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:25373b66e0dd5905ed63fa3cae13c82fbddf3079f2c8bf15c6fb6a35586324c1"},
+ {file = "pillow-12.2.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:bfa9c230d2fe991bed5318a5f119bd6780cda2915cca595393649fc118ab895e"},
+ {file = "pillow-12.2.0.tar.gz", hash = "sha256:a830b1a40919539d07806aa58e1b114df53ddd43213d9c8b75847eee6c0182b5"},
]
[package.extras]
-docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"]
-test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"]
+docs = ["furo", "olefile", "sphinx (>=8.2)", "sphinx-autobuild", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"]
+fpx = ["olefile"]
+mic = ["olefile"]
+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]]
name = "pluggy"
-version = "1.4.0"
+version = "1.6.0"
description = "plugin and hook calling mechanisms for python"
optional = false
-python-versions = ">=3.8"
+python-versions = ">=3.9"
files = [
- {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"},
- {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"},
+ {file = "pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746"},
+ {file = "pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3"},
]
[package.extras]
dev = ["pre-commit", "tox"]
-testing = ["pytest", "pytest-benchmark"]
+testing = ["coverage", "pytest", "pytest-benchmark"]
[[package]]
-name = "pydantic"
-version = "2.6.4"
-description = "Data validation using Python type hints"
+name = "protobuf"
+version = "7.35.0"
+description = ""
optional = false
-python-versions = ">=3.8"
+python-versions = ">=3.10"
files = [
- {file = "pydantic-2.6.4-py3-none-any.whl", hash = "sha256:cc46fce86607580867bdc3361ad462bab9c222ef042d3da86f2fb333e1d916c5"},
- {file = "pydantic-2.6.4.tar.gz", hash = "sha256:b1704e0847db01817624a6b86766967f552dd9dbf3afba4004409f908dcc84e6"},
+ {file = "protobuf-7.35.0-cp310-abi3-macosx_10_9_universal2.whl", hash = "sha256:66be6c513931c794fa92c080ffee41671390da3d79da219cf9c0c0907f035dda"},
+ {file = "protobuf-7.35.0-cp310-abi3-manylinux2014_aarch64.whl", hash = "sha256:fcbe42a4ac09d3ec9c987ddfcd956afd0b15f1ff613bd8371bde9405ffd5c8e5"},
+ {file = "protobuf-7.35.0-cp310-abi3-manylinux2014_s390x.whl", hash = "sha256:4cbf5cc286130e06a6c9bbefac442431173906dfcc979712183d4adcc01b37ee"},
+ {file = "protobuf-7.35.0-cp310-abi3-manylinux2014_x86_64.whl", hash = "sha256:6c0f98f10c8a05ea30f8993dfef2de093d27b490fdae78bb60c8343795d55011"},
+ {file = "protobuf-7.35.0-cp310-abi3-win32.whl", hash = "sha256:4c4617b83ade0e279d1d2bfe04025a1adb87f9ed657de038620dc0ff959357f6"},
+ {file = "protobuf-7.35.0-cp310-abi3-win_amd64.whl", hash = "sha256:f05bcadf9a2a6b8dda047007075135fb7d08c73d9177aabc067e1be46881a201"},
+ {file = "protobuf-7.35.0-py3-none-any.whl", hash = "sha256:c13f325cf242bad135c350629eeb5d54b24228eb472fb3e2e9ebbd4c5dc20ca0"},
+ {file = "protobuf-7.35.0.tar.gz", hash = "sha256:a2efd84605f41e559f1881b0912b44099d0a2ac9bf46b3474823f10fb393b0e6"},
]
-[package.dependencies]
-annotated-types = ">=0.4.0"
-pydantic-core = "2.16.3"
-typing-extensions = ">=4.6.1"
+[[package]]
+name = "pygments"
+version = "2.20.0"
+description = "Pygments is a syntax highlighting package written in Python."
+optional = false
+python-versions = ">=3.9"
+files = [
+ {file = "pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176"},
+ {file = "pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f"},
+]
[package.extras]
-email = ["email-validator (>=2.0.0)"]
+windows-terminal = ["colorama (>=0.4.6)"]
[[package]]
-name = "pydantic-core"
-version = "2.16.3"
-description = ""
+name = "pyparsing"
+version = "3.3.2"
+description = "pyparsing - Classes and methods to define and execute parsing grammars"
optional = false
-python-versions = ">=3.8"
+python-versions = ">=3.9"
files = [
- {file = "pydantic_core-2.16.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:75b81e678d1c1ede0785c7f46690621e4c6e63ccd9192af1f0bd9d504bbb6bf4"},
- {file = "pydantic_core-2.16.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9c865a7ee6f93783bd5d781af5a4c43dadc37053a5b42f7d18dc019f8c9d2bd1"},
- {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:162e498303d2b1c036b957a1278fa0899d02b2842f1ff901b6395104c5554a45"},
- {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f583bd01bbfbff4eaee0868e6fc607efdfcc2b03c1c766b06a707abbc856187"},
- {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b926dd38db1519ed3043a4de50214e0d600d404099c3392f098a7f9d75029ff8"},
- {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:716b542728d4c742353448765aa7cdaa519a7b82f9564130e2b3f6766018c9ec"},
- {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc4ad7f7ee1a13d9cb49d8198cd7d7e3aa93e425f371a68235f784e99741561f"},
- {file = "pydantic_core-2.16.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bd87f48924f360e5d1c5f770d6155ce0e7d83f7b4e10c2f9ec001c73cf475c99"},
- {file = "pydantic_core-2.16.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0df446663464884297c793874573549229f9eca73b59360878f382a0fc085979"},
- {file = "pydantic_core-2.16.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4df8a199d9f6afc5ae9a65f8f95ee52cae389a8c6b20163762bde0426275b7db"},
- {file = "pydantic_core-2.16.3-cp310-none-win32.whl", hash = "sha256:456855f57b413f077dff513a5a28ed838dbbb15082ba00f80750377eed23d132"},
- {file = "pydantic_core-2.16.3-cp310-none-win_amd64.whl", hash = "sha256:732da3243e1b8d3eab8c6ae23ae6a58548849d2e4a4e03a1924c8ddf71a387cb"},
- {file = "pydantic_core-2.16.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:519ae0312616026bf4cedc0fe459e982734f3ca82ee8c7246c19b650b60a5ee4"},
- {file = "pydantic_core-2.16.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b3992a322a5617ded0a9f23fd06dbc1e4bd7cf39bc4ccf344b10f80af58beacd"},
- {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d62da299c6ecb04df729e4b5c52dc0d53f4f8430b4492b93aa8de1f541c4aac"},
- {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2acca2be4bb2f2147ada8cac612f8a98fc09f41c89f87add7256ad27332c2fda"},
- {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1b662180108c55dfbf1280d865b2d116633d436cfc0bba82323554873967b340"},
- {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e7c6ed0dc9d8e65f24f5824291550139fe6f37fac03788d4580da0d33bc00c97"},
- {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6b1bb0827f56654b4437955555dc3aeeebeddc47c2d7ed575477f082622c49e"},
- {file = "pydantic_core-2.16.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e56f8186d6210ac7ece503193ec84104da7ceb98f68ce18c07282fcc2452e76f"},
- {file = "pydantic_core-2.16.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:936e5db01dd49476fa8f4383c259b8b1303d5dd5fb34c97de194560698cc2c5e"},
- {file = "pydantic_core-2.16.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:33809aebac276089b78db106ee692bdc9044710e26f24a9a2eaa35a0f9fa70ba"},
- {file = "pydantic_core-2.16.3-cp311-none-win32.whl", hash = "sha256:ded1c35f15c9dea16ead9bffcde9bb5c7c031bff076355dc58dcb1cb436c4721"},
- {file = "pydantic_core-2.16.3-cp311-none-win_amd64.whl", hash = "sha256:d89ca19cdd0dd5f31606a9329e309d4fcbb3df860960acec32630297d61820df"},
- {file = "pydantic_core-2.16.3-cp311-none-win_arm64.whl", hash = "sha256:6162f8d2dc27ba21027f261e4fa26f8bcb3cf9784b7f9499466a311ac284b5b9"},
- {file = "pydantic_core-2.16.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:0f56ae86b60ea987ae8bcd6654a887238fd53d1384f9b222ac457070b7ac4cff"},
- {file = "pydantic_core-2.16.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9bd22a2a639e26171068f8ebb5400ce2c1bc7d17959f60a3b753ae13c632975"},
- {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4204e773b4b408062960e65468d5346bdfe139247ee5f1ca2a378983e11388a2"},
- {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f651dd19363c632f4abe3480a7c87a9773be27cfe1341aef06e8759599454120"},
- {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aaf09e615a0bf98d406657e0008e4a8701b11481840be7d31755dc9f97c44053"},
- {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8e47755d8152c1ab5b55928ab422a76e2e7b22b5ed8e90a7d584268dd49e9c6b"},
- {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:500960cb3a0543a724a81ba859da816e8cf01b0e6aaeedf2c3775d12ee49cade"},
- {file = "pydantic_core-2.16.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cf6204fe865da605285c34cf1172879d0314ff267b1c35ff59de7154f35fdc2e"},
- {file = "pydantic_core-2.16.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d33dd21f572545649f90c38c227cc8631268ba25c460b5569abebdd0ec5974ca"},
- {file = "pydantic_core-2.16.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:49d5d58abd4b83fb8ce763be7794d09b2f50f10aa65c0f0c1696c677edeb7cbf"},
- {file = "pydantic_core-2.16.3-cp312-none-win32.whl", hash = "sha256:f53aace168a2a10582e570b7736cc5bef12cae9cf21775e3eafac597e8551fbe"},
- {file = "pydantic_core-2.16.3-cp312-none-win_amd64.whl", hash = "sha256:0d32576b1de5a30d9a97f300cc6a3f4694c428d956adbc7e6e2f9cad279e45ed"},
- {file = "pydantic_core-2.16.3-cp312-none-win_arm64.whl", hash = "sha256:ec08be75bb268473677edb83ba71e7e74b43c008e4a7b1907c6d57e940bf34b6"},
- {file = "pydantic_core-2.16.3-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:b1f6f5938d63c6139860f044e2538baeee6f0b251a1816e7adb6cbce106a1f01"},
- {file = "pydantic_core-2.16.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2a1ef6a36fdbf71538142ed604ad19b82f67b05749512e47f247a6ddd06afdc7"},
- {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:704d35ecc7e9c31d48926150afada60401c55efa3b46cd1ded5a01bdffaf1d48"},
- {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d937653a696465677ed583124b94a4b2d79f5e30b2c46115a68e482c6a591c8a"},
- {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9803edf8e29bd825f43481f19c37f50d2b01899448273b3a7758441b512acf8"},
- {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:72282ad4892a9fb2da25defeac8c2e84352c108705c972db82ab121d15f14e6d"},
- {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f752826b5b8361193df55afcdf8ca6a57d0232653494ba473630a83ba50d8c9"},
- {file = "pydantic_core-2.16.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4384a8f68ddb31a0b0c3deae88765f5868a1b9148939c3f4121233314ad5532c"},
- {file = "pydantic_core-2.16.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a4b2bf78342c40b3dc830880106f54328928ff03e357935ad26c7128bbd66ce8"},
- {file = "pydantic_core-2.16.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:13dcc4802961b5f843a9385fc821a0b0135e8c07fc3d9949fd49627c1a5e6ae5"},
- {file = "pydantic_core-2.16.3-cp38-none-win32.whl", hash = "sha256:e3e70c94a0c3841e6aa831edab1619ad5c511199be94d0c11ba75fe06efe107a"},
- {file = "pydantic_core-2.16.3-cp38-none-win_amd64.whl", hash = "sha256:ecdf6bf5f578615f2e985a5e1f6572e23aa632c4bd1dc67f8f406d445ac115ed"},
- {file = "pydantic_core-2.16.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:bda1ee3e08252b8d41fa5537413ffdddd58fa73107171a126d3b9ff001b9b820"},
- {file = "pydantic_core-2.16.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:21b888c973e4f26b7a96491c0965a8a312e13be108022ee510248fe379a5fa23"},
- {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be0ec334369316fa73448cc8c982c01e5d2a81c95969d58b8f6e272884df0074"},
- {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b5b6079cc452a7c53dd378c6f881ac528246b3ac9aae0f8eef98498a75657805"},
- {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ee8d5f878dccb6d499ba4d30d757111847b6849ae07acdd1205fffa1fc1253c"},
- {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7233d65d9d651242a68801159763d09e9ec96e8a158dbf118dc090cd77a104c9"},
- {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6119dc90483a5cb50a1306adb8d52c66e447da88ea44f323e0ae1a5fcb14256"},
- {file = "pydantic_core-2.16.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:578114bc803a4c1ff9946d977c221e4376620a46cf78da267d946397dc9514a8"},
- {file = "pydantic_core-2.16.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d8f99b147ff3fcf6b3cc60cb0c39ea443884d5559a30b1481e92495f2310ff2b"},
- {file = "pydantic_core-2.16.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4ac6b4ce1e7283d715c4b729d8f9dab9627586dafce81d9eaa009dd7f25dd972"},
- {file = "pydantic_core-2.16.3-cp39-none-win32.whl", hash = "sha256:e7774b570e61cb998490c5235740d475413a1f6de823169b4cf94e2fe9e9f6b2"},
- {file = "pydantic_core-2.16.3-cp39-none-win_amd64.whl", hash = "sha256:9091632a25b8b87b9a605ec0e61f241c456e9248bfdcf7abdf344fdb169c81cf"},
- {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:36fa178aacbc277bc6b62a2c3da95226520da4f4e9e206fdf076484363895d2c"},
- {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:dcca5d2bf65c6fb591fff92da03f94cd4f315972f97c21975398bd4bd046854a"},
- {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a72fb9963cba4cd5793854fd12f4cfee731e86df140f59ff52a49b3552db241"},
- {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b60cc1a081f80a2105a59385b92d82278b15d80ebb3adb200542ae165cd7d183"},
- {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cbcc558401de90a746d02ef330c528f2e668c83350f045833543cd57ecead1ad"},
- {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:fee427241c2d9fb7192b658190f9f5fd6dfe41e02f3c1489d2ec1e6a5ab1e04a"},
- {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f4cb85f693044e0f71f394ff76c98ddc1bc0953e48c061725e540396d5c8a2e1"},
- {file = "pydantic_core-2.16.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b29eeb887aa931c2fcef5aa515d9d176d25006794610c264ddc114c053bf96fe"},
- {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a425479ee40ff021f8216c9d07a6a3b54b31c8267c6e17aa88b70d7ebd0e5e5b"},
- {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5c5cbc703168d1b7a838668998308018a2718c2130595e8e190220238addc96f"},
- {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99b6add4c0b39a513d323d3b93bc173dac663c27b99860dd5bf491b240d26137"},
- {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f76ee558751746d6a38f89d60b6228fa174e5172d143886af0f85aa306fd89"},
- {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:00ee1c97b5364b84cb0bd82e9bbf645d5e2871fb8c58059d158412fee2d33d8a"},
- {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:287073c66748f624be4cef893ef9174e3eb88fe0b8a78dc22e88eca4bc357ca6"},
- {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ed25e1835c00a332cb10c683cd39da96a719ab1dfc08427d476bce41b92531fc"},
- {file = "pydantic_core-2.16.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:86b3d0033580bd6bbe07590152007275bd7af95f98eaa5bd36f3da219dcd93da"},
- {file = "pydantic_core-2.16.3.tar.gz", hash = "sha256:1cac689f80a3abab2d3c0048b29eea5751114054f032a941a32de4c852c59cad"},
+ {file = "pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d"},
+ {file = "pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc"},
]
-[package.dependencies]
-typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0"
+[package.extras]
+diagrams = ["jinja2", "railroad-diagrams"]
[[package]]
name = "pytest"
-version = "7.4.4"
+version = "9.0.3"
description = "pytest: simple powerful testing with Python"
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.10"
files = [
- {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"},
- {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"},
+ {file = "pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9"},
+ {file = "pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c"},
]
[package.dependencies]
-colorama = {version = "*", markers = "sys_platform == \"win32\""}
-exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
-iniconfig = "*"
-packaging = "*"
-pluggy = ">=0.12,<2.0"
-tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""}
+colorama = {version = ">=0.4", markers = "sys_platform == \"win32\""}
+exceptiongroup = {version = ">=1", markers = "python_version < \"3.11\""}
+iniconfig = ">=1.0.1"
+packaging = ">=22"
+pluggy = ">=1.5,<2"
+pygments = ">=2.7.2"
+tomli = {version = ">=1", markers = "python_version < \"3.11\""}
[package.extras]
-testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
+dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests", "setuptools", "xmlschema"]
+
+[[package]]
+name = "pytest-asyncio"
+version = "1.3.0"
+description = "Pytest support for asyncio"
+optional = false
+python-versions = ">=3.10"
+files = [
+ {file = "pytest_asyncio-1.3.0-py3-none-any.whl", hash = "sha256:611e26147c7f77640e6d0a92a38ed17c3e9848063698d5c93d5aa7aa11cebff5"},
+ {file = "pytest_asyncio-1.3.0.tar.gz", hash = "sha256:d7f52f36d231b80ee124cd216ffb19369aa168fc10095013c6b014a34d3ee9e5"},
+]
+
+[package.dependencies]
+backports-asyncio-runner = {version = ">=1.1,<2", markers = "python_version < \"3.11\""}
+pytest = ">=8.2,<10"
+typing-extensions = {version = ">=4.12", markers = "python_version < \"3.13\""}
+
+[package.extras]
+docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1)"]
+testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"]
[[package]]
name = "pytest-dotenv"
@@ -813,6 +960,26 @@ files = [
pytest = ">=5.0.0"
python-dotenv = ">=0.9.1"
+[[package]]
+name = "pytest-xdist"
+version = "3.8.0"
+description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs"
+optional = false
+python-versions = ">=3.9"
+files = [
+ {file = "pytest_xdist-3.8.0-py3-none-any.whl", hash = "sha256:202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88"},
+ {file = "pytest_xdist-3.8.0.tar.gz", hash = "sha256:7e578125ec9bc6050861aa93f2d59f1d8d085595d6551c2c90b6f4fad8d3a9f1"},
+]
+
+[package.dependencies]
+execnet = ">=2.1"
+pytest = ">=7.0.0"
+
+[package.extras]
+psutil = ["psutil (>=3.0)"]
+setproctitle = ["setproctitle"]
+testing = ["filelock"]
+
[[package]]
name = "python-dateutil"
version = "2.9.0.post0"
@@ -829,290 +996,156 @@ six = ">=1.5"
[[package]]
name = "python-dotenv"
-version = "1.0.1"
+version = "1.2.2"
description = "Read key-value pairs from a .env file and set them as environment variables"
optional = false
-python-versions = ">=3.8"
+python-versions = ">=3.10"
files = [
- {file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"},
- {file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"},
+ {file = "python_dotenv-1.2.2-py3-none-any.whl", hash = "sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a"},
+ {file = "python_dotenv-1.2.2.tar.gz", hash = "sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3"},
]
[package.extras]
cli = ["click (>=5.0)"]
[[package]]
-name = "requests"
-version = "2.31.0"
-description = "Python HTTP for Humans."
+name = "rich"
+version = "15.0.0"
+description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.9.0"
files = [
- {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"},
- {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"},
+ {file = "rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb"},
+ {file = "rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36"},
]
[package.dependencies]
-certifi = ">=2017.4.17"
-charset-normalizer = ">=2,<4"
-idna = ">=2.5,<4"
-urllib3 = ">=1.21.1,<3"
+markdown-it-py = ">=2.2.0"
+pygments = ">=2.13.0,<3.0.0"
[package.extras]
-socks = ["PySocks (>=1.5.6,!=1.5.7)"]
-use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
+jupyter = ["ipywidgets (>=7.5.1,<9)"]
[[package]]
-name = "six"
-version = "1.16.0"
-description = "Python 2 and 3 compatibility utilities"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
-files = [
- {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
- {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
-]
-
-[[package]]
-name = "tomli"
-version = "2.0.1"
-description = "A lil' TOML parser"
+name = "ruff"
+version = "0.11.13"
+description = "An extremely fast Python linter and code formatter, written in Rust."
optional = false
python-versions = ">=3.7"
files = [
- {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
- {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
-]
-
-[[package]]
-name = "typing-extensions"
-version = "4.10.0"
-description = "Backported and Experimental Type Hints for Python 3.8+"
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"},
- {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"},
+ {file = "ruff-0.11.13-py3-none-linux_armv6l.whl", hash = "sha256:4bdfbf1240533f40042ec00c9e09a3aade6f8c10b6414cf11b519488d2635d46"},
+ {file = "ruff-0.11.13-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:aef9c9ed1b5ca28bb15c7eac83b8670cf3b20b478195bd49c8d756ba0a36cf48"},
+ {file = "ruff-0.11.13-py3-none-macosx_11_0_arm64.whl", hash = "sha256:53b15a9dfdce029c842e9a5aebc3855e9ab7771395979ff85b7c1dedb53ddc2b"},
+ {file = "ruff-0.11.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab153241400789138d13f362c43f7edecc0edfffce2afa6a68434000ecd8f69a"},
+ {file = "ruff-0.11.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6c51f93029d54a910d3d24f7dd0bb909e31b6cd989a5e4ac513f4eb41629f0dc"},
+ {file = "ruff-0.11.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1808b3ed53e1a777c2ef733aca9051dc9bf7c99b26ece15cb59a0320fbdbd629"},
+ {file = "ruff-0.11.13-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d28ce58b5ecf0f43c1b71edffabe6ed7f245d5336b17805803312ec9bc665933"},
+ {file = "ruff-0.11.13-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55e4bc3a77842da33c16d55b32c6cac1ec5fb0fbec9c8c513bdce76c4f922165"},
+ {file = "ruff-0.11.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:633bf2c6f35678c56ec73189ba6fa19ff1c5e4807a78bf60ef487b9dd272cc71"},
+ {file = "ruff-0.11.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ffbc82d70424b275b089166310448051afdc6e914fdab90e08df66c43bb5ca9"},
+ {file = "ruff-0.11.13-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4a9ddd3ec62a9a89578c85842b836e4ac832d4a2e0bfaad3b02243f930ceafcc"},
+ {file = "ruff-0.11.13-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d237a496e0778d719efb05058c64d28b757c77824e04ffe8796c7436e26712b7"},
+ {file = "ruff-0.11.13-py3-none-musllinux_1_2_i686.whl", hash = "sha256:26816a218ca6ef02142343fd24c70f7cd8c5aa6c203bca284407adf675984432"},
+ {file = "ruff-0.11.13-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:51c3f95abd9331dc5b87c47ac7f376db5616041173826dfd556cfe3d4977f492"},
+ {file = "ruff-0.11.13-py3-none-win32.whl", hash = "sha256:96c27935418e4e8e77a26bb05962817f28b8ef3843a6c6cc49d8783b5507f250"},
+ {file = "ruff-0.11.13-py3-none-win_amd64.whl", hash = "sha256:29c3189895a8a6a657b7af4e97d330c8a3afd2c9c8f46c81e2fc5a31866517e3"},
+ {file = "ruff-0.11.13-py3-none-win_arm64.whl", hash = "sha256:b4385285e9179d608ff1d2fb9922062663c658605819a6876d8beef0c30b7f3b"},
+ {file = "ruff-0.11.13.tar.gz", hash = "sha256:26fa247dc68d1d4e72c179e08889a25ac0c7ba4d78aecfc835d49cbfd60bf514"},
]
[[package]]
-name = "urllib3"
-version = "2.2.1"
-description = "HTTP library with thread-safe connection pooling, file post, and more."
+name = "six"
+version = "1.17.0"
+description = "Python 2 and 3 compatibility utilities"
optional = false
-python-versions = ">=3.8"
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
files = [
- {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"},
- {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"},
+ {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"},
+ {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"},
]
-[package.extras]
-brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
-h2 = ["h2 (>=4,<5)"]
-socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
-zstd = ["zstandard (>=0.18.0)"]
-
[[package]]
-name = "websocket-client"
-version = "1.7.0"
-description = "WebSocket client for Python with low level API options"
+name = "tomli"
+version = "2.4.1"
+description = "A lil' TOML parser"
optional = false
python-versions = ">=3.8"
files = [
- {file = "websocket-client-1.7.0.tar.gz", hash = "sha256:10e511ea3a8c744631d3bd77e61eb17ed09304c413ad42cf6ddfa4c7787e8fe6"},
- {file = "websocket_client-1.7.0-py3-none-any.whl", hash = "sha256:f4c3d22fec12a2461427a29957ff07d35098ee2d976d3ba244e688b8b4057588"},
+ {file = "tomli-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30"},
+ {file = "tomli-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a"},
+ {file = "tomli-2.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076"},
+ {file = "tomli-2.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9"},
+ {file = "tomli-2.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c"},
+ {file = "tomli-2.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc"},
+ {file = "tomli-2.4.1-cp311-cp311-win32.whl", hash = "sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049"},
+ {file = "tomli-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e"},
+ {file = "tomli-2.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece"},
+ {file = "tomli-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a"},
+ {file = "tomli-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085"},
+ {file = "tomli-2.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9"},
+ {file = "tomli-2.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5"},
+ {file = "tomli-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585"},
+ {file = "tomli-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1"},
+ {file = "tomli-2.4.1-cp312-cp312-win32.whl", hash = "sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917"},
+ {file = "tomli-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9"},
+ {file = "tomli-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257"},
+ {file = "tomli-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54"},
+ {file = "tomli-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a"},
+ {file = "tomli-2.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897"},
+ {file = "tomli-2.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f"},
+ {file = "tomli-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d"},
+ {file = "tomli-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5"},
+ {file = "tomli-2.4.1-cp313-cp313-win32.whl", hash = "sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd"},
+ {file = "tomli-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36"},
+ {file = "tomli-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd"},
+ {file = "tomli-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf"},
+ {file = "tomli-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac"},
+ {file = "tomli-2.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662"},
+ {file = "tomli-2.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853"},
+ {file = "tomli-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15"},
+ {file = "tomli-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba"},
+ {file = "tomli-2.4.1-cp314-cp314-win32.whl", hash = "sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6"},
+ {file = "tomli-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7"},
+ {file = "tomli-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232"},
+ {file = "tomli-2.4.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4"},
+ {file = "tomli-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c"},
+ {file = "tomli-2.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d"},
+ {file = "tomli-2.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41"},
+ {file = "tomli-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c"},
+ {file = "tomli-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f"},
+ {file = "tomli-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8"},
+ {file = "tomli-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26"},
+ {file = "tomli-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396"},
+ {file = "tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe"},
+ {file = "tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f"},
]
-[package.extras]
-docs = ["Sphinx (>=6.0)", "sphinx-rtd-theme (>=1.1.0)"]
-optional = ["python-socks", "wsaccel"]
-test = ["websockets"]
-
[[package]]
-name = "websockets"
-version = "12.0"
-description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)"
+name = "typing-extensions"
+version = "4.15.0"
+description = "Backported and Experimental Type Hints for Python 3.9+"
optional = false
-python-versions = ">=3.8"
+python-versions = ">=3.9"
files = [
- {file = "websockets-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374"},
- {file = "websockets-12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be"},
- {file = "websockets-12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547"},
- {file = "websockets-12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2"},
- {file = "websockets-12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558"},
- {file = "websockets-12.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480"},
- {file = "websockets-12.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c"},
- {file = "websockets-12.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8"},
- {file = "websockets-12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603"},
- {file = "websockets-12.0-cp310-cp310-win32.whl", hash = "sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f"},
- {file = "websockets-12.0-cp310-cp310-win_amd64.whl", hash = "sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf"},
- {file = "websockets-12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4"},
- {file = "websockets-12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f"},
- {file = "websockets-12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3"},
- {file = "websockets-12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c"},
- {file = "websockets-12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45"},
- {file = "websockets-12.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04"},
- {file = "websockets-12.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447"},
- {file = "websockets-12.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca"},
- {file = "websockets-12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53"},
- {file = "websockets-12.0-cp311-cp311-win32.whl", hash = "sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402"},
- {file = "websockets-12.0-cp311-cp311-win_amd64.whl", hash = "sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b"},
- {file = "websockets-12.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df"},
- {file = "websockets-12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc"},
- {file = "websockets-12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b"},
- {file = "websockets-12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb"},
- {file = "websockets-12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92"},
- {file = "websockets-12.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed"},
- {file = "websockets-12.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5"},
- {file = "websockets-12.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2"},
- {file = "websockets-12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113"},
- {file = "websockets-12.0-cp312-cp312-win32.whl", hash = "sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d"},
- {file = "websockets-12.0-cp312-cp312-win_amd64.whl", hash = "sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f"},
- {file = "websockets-12.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5f6ffe2c6598f7f7207eef9a1228b6f5c818f9f4d53ee920aacd35cec8110438"},
- {file = "websockets-12.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9edf3fc590cc2ec20dc9d7a45108b5bbaf21c0d89f9fd3fd1685e223771dc0b2"},
- {file = "websockets-12.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8572132c7be52632201a35f5e08348137f658e5ffd21f51f94572ca6c05ea81d"},
- {file = "websockets-12.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:604428d1b87edbf02b233e2c207d7d528460fa978f9e391bd8aaf9c8311de137"},
- {file = "websockets-12.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a9d160fd080c6285e202327aba140fc9a0d910b09e423afff4ae5cbbf1c7205"},
- {file = "websockets-12.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87b4aafed34653e465eb77b7c93ef058516cb5acf3eb21e42f33928616172def"},
- {file = "websockets-12.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b2ee7288b85959797970114deae81ab41b731f19ebcd3bd499ae9ca0e3f1d2c8"},
- {file = "websockets-12.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7fa3d25e81bfe6a89718e9791128398a50dec6d57faf23770787ff441d851967"},
- {file = "websockets-12.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a571f035a47212288e3b3519944f6bf4ac7bc7553243e41eac50dd48552b6df7"},
- {file = "websockets-12.0-cp38-cp38-win32.whl", hash = "sha256:3c6cc1360c10c17463aadd29dd3af332d4a1adaa8796f6b0e9f9df1fdb0bad62"},
- {file = "websockets-12.0-cp38-cp38-win_amd64.whl", hash = "sha256:1bf386089178ea69d720f8db6199a0504a406209a0fc23e603b27b300fdd6892"},
- {file = "websockets-12.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ab3d732ad50a4fbd04a4490ef08acd0517b6ae6b77eb967251f4c263011a990d"},
- {file = "websockets-12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a1d9697f3337a89691e3bd8dc56dea45a6f6d975f92e7d5f773bc715c15dde28"},
- {file = "websockets-12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1df2fbd2c8a98d38a66f5238484405b8d1d16f929bb7a33ed73e4801222a6f53"},
- {file = "websockets-12.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23509452b3bc38e3a057382c2e941d5ac2e01e251acce7adc74011d7d8de434c"},
- {file = "websockets-12.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e5fc14ec6ea568200ea4ef46545073da81900a2b67b3e666f04adf53ad452ec"},
- {file = "websockets-12.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46e71dbbd12850224243f5d2aeec90f0aaa0f2dde5aeeb8fc8df21e04d99eff9"},
- {file = "websockets-12.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b81f90dcc6c85a9b7f29873beb56c94c85d6f0dac2ea8b60d995bd18bf3e2aae"},
- {file = "websockets-12.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a02413bc474feda2849c59ed2dfb2cddb4cd3d2f03a2fedec51d6e959d9b608b"},
- {file = "websockets-12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bbe6013f9f791944ed31ca08b077e26249309639313fff132bfbf3ba105673b9"},
- {file = "websockets-12.0-cp39-cp39-win32.whl", hash = "sha256:cbe83a6bbdf207ff0541de01e11904827540aa069293696dd528a6640bd6a5f6"},
- {file = "websockets-12.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc4e7fa5414512b481a2483775a8e8be7803a35b30ca805afa4998a84f9fd9e8"},
- {file = "websockets-12.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd"},
- {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870"},
- {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077"},
- {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b"},
- {file = "websockets-12.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30"},
- {file = "websockets-12.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0bee75f400895aef54157b36ed6d3b308fcab62e5260703add87f44cee9c82a6"},
- {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:423fc1ed29f7512fceb727e2d2aecb952c46aa34895e9ed96071821309951123"},
- {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27a5e9964ef509016759f2ef3f2c1e13f403725a5e6a1775555994966a66e931"},
- {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3181df4583c4d3994d31fb235dc681d2aaad744fbdbf94c4802485ececdecf2"},
- {file = "websockets-12.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b067cb952ce8bf40115f6c19f478dc71c5e719b7fbaa511359795dfd9d1a6468"},
- {file = "websockets-12.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:00700340c6c7ab788f176d118775202aadea7602c5cc6be6ae127761c16d6b0b"},
- {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e469d01137942849cff40517c97a30a93ae79917752b34029f0ec72df6b46399"},
- {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7"},
- {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba0cab91b3956dfa9f512147860783a1829a8d905ee218a9837c18f683239611"},
- {file = "websockets-12.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2cb388a5bfb56df4d9a406783b7f9dbefb888c09b71629351cc6b036e9259370"},
- {file = "websockets-12.0-py3-none-any.whl", hash = "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e"},
- {file = "websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"},
+ {file = "typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"},
+ {file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"},
]
[[package]]
-name = "yarl"
-version = "1.9.4"
-description = "Yet another URL library"
+name = "wcmatch"
+version = "10.1"
+description = "Wildcard/glob file name matcher."
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.9"
files = [
- {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e"},
- {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3a6ed1d525bfb91b3fc9b690c5a21bb52de28c018530ad85093cc488bee2dd2"},
- {file = "yarl-1.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c38c9ddb6103ceae4e4498f9c08fac9b590c5c71b0370f98714768e22ac6fa66"},
- {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9e09c9d74f4566e905a0b8fa668c58109f7624db96a2171f21747abc7524234"},
- {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8477c1ee4bd47c57d49621a062121c3023609f7a13b8a46953eb6c9716ca392"},
- {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5ff2c858f5f6a42c2a8e751100f237c5e869cbde669a724f2062d4c4ef93551"},
- {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:357495293086c5b6d34ca9616a43d329317feab7917518bc97a08f9e55648455"},
- {file = "yarl-1.9.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54525ae423d7b7a8ee81ba189f131054defdb122cde31ff17477951464c1691c"},
- {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:801e9264d19643548651b9db361ce3287176671fb0117f96b5ac0ee1c3530d53"},
- {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e516dc8baf7b380e6c1c26792610230f37147bb754d6426462ab115a02944385"},
- {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7d5aaac37d19b2904bb9dfe12cdb08c8443e7ba7d2852894ad448d4b8f442863"},
- {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:54beabb809ffcacbd9d28ac57b0db46e42a6e341a030293fb3185c409e626b8b"},
- {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bac8d525a8dbc2a1507ec731d2867025d11ceadcb4dd421423a5d42c56818541"},
- {file = "yarl-1.9.4-cp310-cp310-win32.whl", hash = "sha256:7855426dfbddac81896b6e533ebefc0af2f132d4a47340cee6d22cac7190022d"},
- {file = "yarl-1.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:848cd2a1df56ddbffeb375535fb62c9d1645dde33ca4d51341378b3f5954429b"},
- {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:35a2b9396879ce32754bd457d31a51ff0a9d426fd9e0e3c33394bf4b9036b099"},
- {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c7d56b293cc071e82532f70adcbd8b61909eec973ae9d2d1f9b233f3d943f2c"},
- {file = "yarl-1.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8a1c6c0be645c745a081c192e747c5de06e944a0d21245f4cf7c05e457c36e0"},
- {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b3c1ffe10069f655ea2d731808e76e0f452fc6c749bea04781daf18e6039525"},
- {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:549d19c84c55d11687ddbd47eeb348a89df9cb30e1993f1b128f4685cd0ebbf8"},
- {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7409f968456111140c1c95301cadf071bd30a81cbd7ab829169fb9e3d72eae9"},
- {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e23a6d84d9d1738dbc6e38167776107e63307dfc8ad108e580548d1f2c587f42"},
- {file = "yarl-1.9.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8b889777de69897406c9fb0b76cdf2fd0f31267861ae7501d93003d55f54fbe"},
- {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce"},
- {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e9035df8d0880b2f1c7f5031f33f69e071dfe72ee9310cfc76f7b605958ceb9"},
- {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c0ec0ed476f77db9fb29bca17f0a8fcc7bc97ad4c6c1d8959c507decb22e8572"},
- {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:ee04010f26d5102399bd17f8df8bc38dc7ccd7701dc77f4a68c5b8d733406958"},
- {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:49a180c2e0743d5d6e0b4d1a9e5f633c62eca3f8a86ba5dd3c471060e352ca98"},
- {file = "yarl-1.9.4-cp311-cp311-win32.whl", hash = "sha256:81eb57278deb6098a5b62e88ad8281b2ba09f2f1147c4767522353eaa6260b31"},
- {file = "yarl-1.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:d1d2532b340b692880261c15aee4dc94dd22ca5d61b9db9a8a361953d36410b1"},
- {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81"},
- {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:44d8ffbb9c06e5a7f529f38f53eda23e50d1ed33c6c869e01481d3fafa6b8142"},
- {file = "yarl-1.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aaaea1e536f98754a6e5c56091baa1b6ce2f2700cc4a00b0d49eca8dea471074"},
- {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3777ce5536d17989c91696db1d459574e9a9bd37660ea7ee4d3344579bb6f129"},
- {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fc5fc1eeb029757349ad26bbc5880557389a03fa6ada41703db5e068881e5f2"},
- {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea65804b5dc88dacd4a40279af0cdadcfe74b3e5b4c897aa0d81cf86927fee78"},
- {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa102d6d280a5455ad6a0f9e6d769989638718e938a6a0a2ff3f4a7ff8c62cc4"},
- {file = "yarl-1.9.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09efe4615ada057ba2d30df871d2f668af661e971dfeedf0c159927d48bbeff0"},
- {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51"},
- {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6f5cb257bc2ec58f437da2b37a8cd48f666db96d47b8a3115c29f316313654ff"},
- {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:992f18e0ea248ee03b5a6e8b3b4738850ae7dbb172cc41c966462801cbf62cf7"},
- {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0e9d124c191d5b881060a9e5060627694c3bdd1fe24c5eecc8d5d7d0eb6faabc"},
- {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3986b6f41ad22988e53d5778f91855dc0399b043fc8946d4f2e68af22ee9ff10"},
- {file = "yarl-1.9.4-cp312-cp312-win32.whl", hash = "sha256:4b21516d181cd77ebd06ce160ef8cc2a5e9ad35fb1c5930882baff5ac865eee7"},
- {file = "yarl-1.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a9bd00dc3bc395a662900f33f74feb3e757429e545d831eef5bb280252631984"},
- {file = "yarl-1.9.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:63b20738b5aac74e239622d2fe30df4fca4942a86e31bf47a81a0e94c14df94f"},
- {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7d7f7de27b8944f1fee2c26a88b4dabc2409d2fea7a9ed3df79b67277644e17"},
- {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c74018551e31269d56fab81a728f683667e7c28c04e807ba08f8c9e3bba32f14"},
- {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca06675212f94e7a610e85ca36948bb8fc023e458dd6c63ef71abfd482481aa5"},
- {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aef935237d60a51a62b86249839b51345f47564208c6ee615ed2a40878dccdd"},
- {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b134fd795e2322b7684155b7855cc99409d10b2e408056db2b93b51a52accc7"},
- {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d25039a474c4c72a5ad4b52495056f843a7ff07b632c1b92ea9043a3d9950f6e"},
- {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f7d6b36dd2e029b6bcb8a13cf19664c7b8e19ab3a58e0fefbb5b8461447ed5ec"},
- {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:957b4774373cf6f709359e5c8c4a0af9f6d7875db657adb0feaf8d6cb3c3964c"},
- {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d7eeb6d22331e2fd42fce928a81c697c9ee2d51400bd1a28803965883e13cead"},
- {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6a962e04b8f91f8c4e5917e518d17958e3bdee71fd1d8b88cdce74dd0ebbf434"},
- {file = "yarl-1.9.4-cp37-cp37m-win32.whl", hash = "sha256:f3bc6af6e2b8f92eced34ef6a96ffb248e863af20ef4fde9448cc8c9b858b749"},
- {file = "yarl-1.9.4-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4d7a90a92e528aadf4965d685c17dacff3df282db1121136c382dc0b6014d2"},
- {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ec61d826d80fc293ed46c9dd26995921e3a82146feacd952ef0757236fc137be"},
- {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8be9e837ea9113676e5754b43b940b50cce76d9ed7d2461df1af39a8ee674d9f"},
- {file = "yarl-1.9.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bef596fdaa8f26e3d66af846bbe77057237cb6e8efff8cd7cc8dff9a62278bbf"},
- {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d47552b6e52c3319fede1b60b3de120fe83bde9b7bddad11a69fb0af7db32f1"},
- {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84fc30f71689d7fc9168b92788abc977dc8cefa806909565fc2951d02f6b7d57"},
- {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4aa9741085f635934f3a2583e16fcf62ba835719a8b2b28fb2917bb0537c1dfa"},
- {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:206a55215e6d05dbc6c98ce598a59e6fbd0c493e2de4ea6cc2f4934d5a18d130"},
- {file = "yarl-1.9.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07574b007ee20e5c375a8fe4a0789fad26db905f9813be0f9fef5a68080de559"},
- {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5a2e2433eb9344a163aced6a5f6c9222c0786e5a9e9cac2c89f0b28433f56e23"},
- {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6ad6d10ed9b67a382b45f29ea028f92d25bc0bc1daf6c5b801b90b5aa70fb9ec"},
- {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6fe79f998a4052d79e1c30eeb7d6c1c1056ad33300f682465e1b4e9b5a188b78"},
- {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a825ec844298c791fd28ed14ed1bffc56a98d15b8c58a20e0e08c1f5f2bea1be"},
- {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8619d6915b3b0b34420cf9b2bb6d81ef59d984cb0fde7544e9ece32b4b3043c3"},
- {file = "yarl-1.9.4-cp38-cp38-win32.whl", hash = "sha256:686a0c2f85f83463272ddffd4deb5e591c98aac1897d65e92319f729c320eece"},
- {file = "yarl-1.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:a00862fb23195b6b8322f7d781b0dc1d82cb3bcac346d1e38689370cc1cc398b"},
- {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:604f31d97fa493083ea21bd9b92c419012531c4e17ea6da0f65cacdcf5d0bd27"},
- {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8a854227cf581330ffa2c4824d96e52ee621dd571078a252c25e3a3b3d94a1b1"},
- {file = "yarl-1.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ba6f52cbc7809cd8d74604cce9c14868306ae4aa0282016b641c661f981a6e91"},
- {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6327976c7c2f4ee6816eff196e25385ccc02cb81427952414a64811037bbc8b"},
- {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8397a3817d7dcdd14bb266283cd1d6fc7264a48c186b986f32e86d86d35fbac5"},
- {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0381b4ce23ff92f8170080c97678040fc5b08da85e9e292292aba67fdac6c34"},
- {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23d32a2594cb5d565d358a92e151315d1b2268bc10f4610d098f96b147370136"},
- {file = "yarl-1.9.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ddb2a5c08a4eaaba605340fdee8fc08e406c56617566d9643ad8bf6852778fc7"},
- {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:26a1dc6285e03f3cc9e839a2da83bcbf31dcb0d004c72d0730e755b33466c30e"},
- {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:18580f672e44ce1238b82f7fb87d727c4a131f3a9d33a5e0e82b793362bf18b4"},
- {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:29e0f83f37610f173eb7e7b5562dd71467993495e568e708d99e9d1944f561ec"},
- {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:1f23e4fe1e8794f74b6027d7cf19dc25f8b63af1483d91d595d4a07eca1fb26c"},
- {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:db8e58b9d79200c76956cefd14d5c90af54416ff5353c5bfd7cbe58818e26ef0"},
- {file = "yarl-1.9.4-cp39-cp39-win32.whl", hash = "sha256:c7224cab95645c7ab53791022ae77a4509472613e839dab722a72abe5a684575"},
- {file = "yarl-1.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:824d6c50492add5da9374875ce72db7a0733b29c2394890aef23d533106e2b15"},
- {file = "yarl-1.9.4-py3-none-any.whl", hash = "sha256:928cecb0ef9d5a7946eb6ff58417ad2fe9375762382f1bf5c55e61645f2c43ad"},
- {file = "yarl-1.9.4.tar.gz", hash = "sha256:566db86717cf8080b99b58b083b773a908ae40f06681e87e589a976faf8246bf"},
+ {file = "wcmatch-10.1-py3-none-any.whl", hash = "sha256:5848ace7dbb0476e5e55ab63c6bbd529745089343427caa5537f230cc01beb8a"},
+ {file = "wcmatch-10.1.tar.gz", hash = "sha256:f11f94208c8c8484a16f4f48638a85d771d9513f4ab3f37595978801cb9465af"},
]
[package.dependencies]
-idna = ">=2.0"
-multidict = ">=4.0"
+bracex = ">=2.1.1"
[metadata]
lock-version = "2.0"
-python-versions = "^3.8"
-content-hash = "fbdc1fb687f8a8fbe8d0b0bb631e5c3cc1a0de62ed3b23538bd314b38b1cdbf5"
+python-versions = "^3.10"
+content-hash = "4b9fdae45121bdfe70eafce86abac886c8379200b6689d0d99a24aef87b152d7"
diff --git a/python/pyproject.toml b/python/pyproject.toml
index d1e41ead..33381043 100644
--- a/python/pyproject.toml
+++ b/python/pyproject.toml
@@ -1,26 +1,30 @@
[tool.poetry]
name = "e2b-code-interpreter"
-version = "0.0.5"
+version = "2.8.0"
description = "E2B Code Interpreter - Stateful code execution"
authors = ["e2b "]
-license = "Apache-2.0"
+license = "MIT"
readme = "README.md"
homepage = "https://e2b.dev/"
-repository = "https://github.com/e2b-dev/e2b-code-interpreter/tree/python"
+repository = "https://github.com/e2b-dev/code-interpreter/tree/main/python"
packages = [{ include = "e2b_code_interpreter" }]
[tool.poetry.dependencies]
-python = "^3.8"
+python = "^3.10"
-pydantic = ">1, <3"
-websocket-client = "^1.7.0"
-e2b = ">=0.17.0"
+httpx = ">=0.20.0, <1.0.0"
+attrs = ">=21.3.0"
+e2b = "^2.26.0"
[tool.poetry.group.dev.dependencies]
-black = "^24.3.0"
-pytest = "^7.4.0"
+pytest = "^9.0.3"
python-dotenv = "^1.0.0"
pytest-dotenv = "^0.5.2"
+pytest-asyncio = "^1.3.0"
+pytest-xdist = "^3.6.1"
+matplotlib = "^3.8.0"
+ruff = "^0.11.12"
+
[build-system]
requires = ["poetry-core"]
@@ -28,3 +32,6 @@ build-backend = "poetry.core.masonry.api"
[tool.poetry.urls]
"Bug Tracker" = "https://github.com/e2b-dev/code-interpreter/issues"
+
+[tool.ruff.lint]
+ignore = ["F401", "F403"]
diff --git a/python/pytest.ini b/python/pytest.ini
new file mode 100644
index 00000000..5d05c876
--- /dev/null
+++ b/python/pytest.ini
@@ -0,0 +1,9 @@
+# content of pytest.ini
+[pytest]
+markers =
+ skip_debug: skip test if E2B_DEBUG is set.
+asyncio_mode = auto
+asyncio_default_fixture_loop_scope = session
+asyncio_default_test_loop_scope = session
+
+addopts = "--import-mode=importlib" "--numprocesses=2"
diff --git a/python/tests/async/env_vars/test_bash.py b/python/tests/async/env_vars/test_bash.py
new file mode 100644
index 00000000..b94563f9
--- /dev/null
+++ b/python/tests/async/env_vars/test_bash.py
@@ -0,0 +1,43 @@
+import pytest
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+
+
+@pytest.mark.skip_debug()
+async def test_env_vars_on_sandbox(template):
+ sandbox = await AsyncSandbox.create(
+ template=template, envs={"TEST_ENV_VAR": "supertest"}
+ )
+ try:
+ result = await sandbox.run_code("echo $TEST_ENV_VAR", language="bash")
+ assert result.logs.stdout[0] == "supertest\n"
+ finally:
+ await sandbox.kill()
+
+
+async def test_env_vars_per_execution(async_sandbox: AsyncSandbox):
+ result = await async_sandbox.run_code(
+ "echo $FOO", envs={"FOO": "bar"}, language="bash"
+ )
+
+ result_empty = await async_sandbox.run_code("echo ${FOO:-default}", language="bash")
+
+ assert result.logs.stdout[0] == "bar\n"
+ assert result_empty.logs.stdout[0] == "default\n"
+
+
+@pytest.mark.skip_debug()
+async def test_env_vars_overwrite(template):
+ sandbox = await AsyncSandbox.create(
+ template=template, envs={"TEST_ENV_VAR": "supertest"}
+ )
+ try:
+ result = await sandbox.run_code(
+ "echo $TEST_ENV_VAR", language="bash", envs={"TEST_ENV_VAR": "overwrite"}
+ )
+ result_global_default = await sandbox.run_code(
+ "echo $TEST_ENV_VAR", language="bash"
+ )
+ assert result.logs.stdout[0] == "overwrite\n"
+ assert result_global_default.logs.stdout[0] == "supertest\n"
+ finally:
+ await sandbox.kill()
diff --git a/python/tests/async/env_vars/test_java.py b/python/tests/async/env_vars/test_java.py
new file mode 100644
index 00000000..d33517c8
--- /dev/null
+++ b/python/tests/async/env_vars/test_java.py
@@ -0,0 +1,54 @@
+import pytest
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+
+
+@pytest.mark.skip_debug()
+async def test_env_vars_on_sandbox(template):
+ sandbox = await AsyncSandbox.create(
+ template=template, envs={"TEST_ENV_VAR": "supertest"}
+ )
+ try:
+ result = await sandbox.run_code(
+ 'System.getProperty("TEST_ENV_VAR")', language="java"
+ )
+ assert result.text is not None
+ assert result.text.strip() == "supertest"
+ finally:
+ await sandbox.kill()
+
+
+async def test_env_vars_per_execution(async_sandbox: AsyncSandbox):
+ result = await async_sandbox.run_code(
+ 'System.getProperty("FOO")', envs={"FOO": "bar"}, language="java"
+ )
+
+ result_empty = await async_sandbox.run_code(
+ 'System.getProperty("FOO", "default")', language="java"
+ )
+
+ assert result.text is not None
+ assert result.text.strip() == "bar"
+ assert result_empty.text is not None
+ assert result_empty.text.strip() == "default"
+
+
+@pytest.mark.skip_debug()
+async def test_env_vars_overwrite(template):
+ sandbox = await AsyncSandbox.create(
+ template=template, envs={"TEST_ENV_VAR": "supertest"}
+ )
+ try:
+ result = await sandbox.run_code(
+ 'System.getProperty("TEST_ENV_VAR")',
+ language="java",
+ envs={"TEST_ENV_VAR": "overwrite"},
+ )
+ result_global_default = await sandbox.run_code(
+ 'System.getProperty("TEST_ENV_VAR")', language="java"
+ )
+ assert result.text is not None
+ assert result.text.strip() == "overwrite"
+ assert result_global_default.text is not None
+ assert result_global_default.text.strip() == "supertest"
+ finally:
+ await sandbox.kill()
diff --git a/python/tests/async/env_vars/test_js.py b/python/tests/async/env_vars/test_js.py
new file mode 100644
index 00000000..3fa21f27
--- /dev/null
+++ b/python/tests/async/env_vars/test_js.py
@@ -0,0 +1,54 @@
+import pytest
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+
+
+@pytest.mark.skip_debug()
+async def test_env_vars_on_sandbox(template):
+ sandbox = await AsyncSandbox.create(
+ template=template, envs={"TEST_ENV_VAR": "supertest"}
+ )
+ try:
+ result = await sandbox.run_code(
+ "process.env.TEST_ENV_VAR", language="javascript"
+ )
+ assert result.text is not None
+ assert result.text.strip() == "supertest"
+ finally:
+ await sandbox.kill()
+
+
+async def test_env_vars_per_execution(async_sandbox: AsyncSandbox):
+ result = await async_sandbox.run_code(
+ "process.env.FOO", envs={"FOO": "bar"}, language="javascript"
+ )
+
+ result_empty = await async_sandbox.run_code(
+ "process.env.FOO || 'default'", language="javascript"
+ )
+
+ assert result.text is not None
+ assert result.text.strip() == "bar"
+ assert result_empty.text is not None
+ assert result_empty.text.strip() == "default"
+
+
+@pytest.mark.skip_debug()
+async def test_env_vars_overwrite(template):
+ sandbox = await AsyncSandbox.create(
+ template=template, envs={"TEST_ENV_VAR": "supertest"}
+ )
+ try:
+ result = await sandbox.run_code(
+ "process.env.TEST_ENV_VAR",
+ language="javascript",
+ envs={"TEST_ENV_VAR": "overwrite"},
+ )
+ result_global_default = await sandbox.run_code(
+ "process.env.TEST_ENV_VAR", language="javascript"
+ )
+ assert result.text is not None
+ assert result.text.strip() == "overwrite"
+ assert result_global_default.text is not None
+ assert result_global_default.text.strip() == "supertest"
+ finally:
+ await sandbox.kill()
diff --git a/python/tests/async/env_vars/test_python.py b/python/tests/async/env_vars/test_python.py
new file mode 100644
index 00000000..3173efc9
--- /dev/null
+++ b/python/tests/async/env_vars/test_python.py
@@ -0,0 +1,54 @@
+import pytest
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+
+
+@pytest.mark.skip_debug()
+async def test_env_vars_on_sandbox(template):
+ sandbox = await AsyncSandbox.create(
+ template=template, envs={"TEST_ENV_VAR": "supertest"}
+ )
+ try:
+ result = await sandbox.run_code(
+ "import os; os.getenv('TEST_ENV_VAR')", language="python"
+ )
+ assert result.text is not None
+ assert result.text.strip() == "supertest"
+ finally:
+ await sandbox.kill()
+
+
+async def test_env_vars_per_execution(async_sandbox: AsyncSandbox):
+ result = await async_sandbox.run_code(
+ "import os; os.getenv('FOO')", envs={"FOO": "bar"}, language="python"
+ )
+
+ result_empty = await async_sandbox.run_code(
+ "import os; os.getenv('FOO', 'default')", language="python"
+ )
+
+ assert result.text is not None
+ assert result.text.strip() == "bar"
+ assert result_empty.text is not None
+ assert result_empty.text.strip() == "default"
+
+
+@pytest.mark.skip_debug()
+async def test_env_vars_overwrite(template):
+ sandbox = await AsyncSandbox.create(
+ template=template, envs={"TEST_ENV_VAR": "supertest"}
+ )
+ try:
+ result = await sandbox.run_code(
+ "import os; os.getenv('TEST_ENV_VAR')",
+ language="python",
+ envs={"TEST_ENV_VAR": "overwrite"},
+ )
+ result_global_default = await sandbox.run_code(
+ "import os; os.getenv('TEST_ENV_VAR')", language="python"
+ )
+ assert result.text is not None
+ assert result.text.strip() == "overwrite"
+ assert result_global_default.text is not None
+ assert result_global_default.text.strip() == "supertest"
+ finally:
+ await sandbox.kill()
diff --git a/python/tests/async/env_vars/test_r.py b/python/tests/async/env_vars/test_r.py
new file mode 100644
index 00000000..6ba95651
--- /dev/null
+++ b/python/tests/async/env_vars/test_r.py
@@ -0,0 +1,52 @@
+import pytest
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+
+
+@pytest.mark.skip_debug()
+async def test_env_vars_on_sandbox(template):
+ sandbox = await AsyncSandbox.create(
+ template=template, envs={"TEST_ENV_VAR": "supertest"}
+ )
+ try:
+ result = await sandbox.run_code('Sys.getenv("TEST_ENV_VAR")', language="r")
+ assert result.results[0].text is not None
+ assert result.results[0].text.strip() == '[1] "supertest"'
+ finally:
+ await sandbox.kill()
+
+
+async def test_env_vars_per_execution(async_sandbox: AsyncSandbox):
+ result = await async_sandbox.run_code(
+ 'Sys.getenv("FOO")', envs={"FOO": "bar"}, language="r"
+ )
+
+ result_empty = await async_sandbox.run_code(
+ 'Sys.getenv("FOO", unset = "default")', language="r"
+ )
+
+ assert result.results[0].text is not None
+ assert result.results[0].text.strip() == '[1] "bar"'
+ assert result_empty.results[0].text is not None
+ assert result_empty.results[0].text.strip() == '[1] "default"'
+
+
+@pytest.mark.skip_debug()
+async def test_env_vars_overwrite(template):
+ sandbox = await AsyncSandbox.create(
+ template=template, envs={"TEST_ENV_VAR": "supertest"}
+ )
+ try:
+ result = await sandbox.run_code(
+ 'Sys.getenv("TEST_ENV_VAR")',
+ language="r",
+ envs={"TEST_ENV_VAR": "overwrite"},
+ )
+ result_global_default = await sandbox.run_code(
+ 'Sys.getenv("TEST_ENV_VAR")', language="r"
+ )
+ assert result.results[0].text is not None
+ assert result.results[0].text.strip() == '[1] "overwrite"'
+ assert result_global_default.results[0].text is not None
+ assert result_global_default.results[0].text.strip() == '[1] "supertest"'
+ finally:
+ await sandbox.kill()
diff --git a/python/tests/async/test_async_bash.py b/python/tests/async/test_async_bash.py
new file mode 100644
index 00000000..a9e2cb0c
--- /dev/null
+++ b/python/tests/async/test_async_bash.py
@@ -0,0 +1,6 @@
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+
+
+async def test_bash(async_sandbox: AsyncSandbox):
+ result = await async_sandbox.run_code("!pwd")
+ assert "".join(result.logs.stdout).strip() == "/home/user"
diff --git a/python/tests/async/test_async_basic.py b/python/tests/async/test_async_basic.py
new file mode 100644
index 00000000..cf1b0bb1
--- /dev/null
+++ b/python/tests/async/test_async_basic.py
@@ -0,0 +1,16 @@
+import pytest
+
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+
+
+async def test_basic(async_sandbox: AsyncSandbox):
+ result = await async_sandbox.run_code("x =1; x")
+ assert result.text == "1"
+
+
+@pytest.mark.skip_debug
+async def test_secure_access(async_sandbox_factory):
+ # Create sandbox with public traffic disabled (secure access)
+ async_sandbox = await async_sandbox_factory(network={"allow_public_traffic": False})
+ result = await async_sandbox.run_code("x =1; x")
+ assert result.text == "1"
diff --git a/python/tests/async/test_async_callbacks.py b/python/tests/async/test_async_callbacks.py
new file mode 100644
index 00000000..49d84903
--- /dev/null
+++ b/python/tests/async/test_async_callbacks.py
@@ -0,0 +1,54 @@
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+
+
+def async_append_fn(items):
+ async def async_append(item):
+ items.append(item)
+
+ return async_append
+
+
+async def test_results(async_sandbox: AsyncSandbox):
+ results = []
+
+ execution = await async_sandbox.run_code(
+ "x = 1;x", on_result=async_append_fn(results)
+ )
+ assert len(results) == 1
+ assert execution.results[0].text == "1"
+
+
+async def test_results_sync_callback(async_sandbox: AsyncSandbox):
+ results = []
+
+ execution = await async_sandbox.run_code(
+ "x = 1;x", on_result=lambda result: results.append(result)
+ )
+ assert len(results) == 1
+ assert execution.results[0].text == "1"
+
+
+async def test_error(async_sandbox: AsyncSandbox):
+ errors = []
+ execution = await async_sandbox.run_code("xyz", on_error=async_append_fn(errors))
+ assert len(errors) == 1
+ assert execution.error.name == "NameError"
+
+
+async def test_stdout(async_sandbox: AsyncSandbox):
+ stdout = []
+ execution = await async_sandbox.run_code(
+ "print('Hello from e2b')", on_stdout=async_append_fn(stdout)
+ )
+ assert len(stdout) == 1
+ assert execution.logs.stdout == ["Hello from e2b\n"]
+
+
+async def test_stderr(async_sandbox: AsyncSandbox):
+ stderr = []
+ execution = await async_sandbox.run_code(
+ 'import sys;print("This is an error message", file=sys.stderr)',
+ on_stderr=async_append_fn(stderr),
+ )
+ assert len(stderr) == 1
+ assert execution.logs.stderr == ["This is an error message\n"]
diff --git a/python/tests/async/test_async_contexts.py b/python/tests/async/test_async_contexts.py
new file mode 100644
index 00000000..0f533f8f
--- /dev/null
+++ b/python/tests/async/test_async_contexts.py
@@ -0,0 +1,127 @@
+import pytest
+
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+
+
+async def test_create_context_with_no_options(async_sandbox: AsyncSandbox):
+ context = await async_sandbox.create_code_context()
+
+ contexts = await async_sandbox.list_code_contexts()
+ last_context = contexts[-1]
+
+ assert last_context.id == context.id
+ assert last_context.language == context.language
+ assert last_context.cwd == context.cwd
+
+
+async def test_create_context_with_options(async_sandbox: AsyncSandbox):
+ context = await async_sandbox.create_code_context(
+ language="python",
+ cwd="/root",
+ )
+
+ contexts = await async_sandbox.list_code_contexts()
+ last_context = contexts[-1]
+
+ assert last_context.id == context.id
+ assert last_context.language == context.language
+ assert last_context.cwd == context.cwd
+
+
+async def test_remove_context(async_sandbox: AsyncSandbox):
+ context = await async_sandbox.create_code_context()
+
+ await async_sandbox.remove_code_context(context.id)
+
+ contexts = await async_sandbox.list_code_contexts()
+ assert context.id not in [ctx.id for ctx in contexts]
+
+
+async def test_list_contexts(async_sandbox: AsyncSandbox):
+ contexts = await async_sandbox.list_code_contexts()
+
+ # default contexts should include python and javascript
+ languages = [context.language for context in contexts]
+ assert "python" in languages
+ assert "javascript" in languages
+
+
+async def test_restart_context(async_sandbox: AsyncSandbox):
+ context = await async_sandbox.create_code_context()
+
+ # set a variable in the context
+ await async_sandbox.run_code("x = 1", context=context)
+
+ # restart the context
+ await async_sandbox.restart_code_context(context.id)
+
+ # check that the variable no longer exists
+ execution = await async_sandbox.run_code("x", context=context)
+
+ # check for a NameError with message "name 'x' is not defined"
+ assert execution.error is not None
+ assert execution.error.name == "NameError"
+ assert execution.error.value == "name 'x' is not defined"
+
+
+@pytest.mark.skip_debug
+async def test_create_context_secure_traffic(async_sandbox_factory):
+ async_sandbox = await async_sandbox_factory(
+ secure=True, network={"allow_public_traffic": False}
+ )
+ context = await async_sandbox.create_code_context()
+
+ contexts = await async_sandbox.list_code_contexts()
+ last_context = contexts[-1]
+
+ assert last_context.id == context.id
+ assert last_context.language == context.language
+ assert last_context.cwd == context.cwd
+
+
+@pytest.mark.skip_debug
+async def test_remove_context_secure_traffic(async_sandbox_factory):
+ async_sandbox = await async_sandbox_factory(
+ secure=True, network={"allow_public_traffic": False}
+ )
+ context = await async_sandbox.create_code_context()
+
+ await async_sandbox.remove_code_context(context.id)
+
+ contexts = await async_sandbox.list_code_contexts()
+ assert context.id not in [ctx.id for ctx in contexts]
+
+
+@pytest.mark.skip_debug
+async def test_list_contexts_secure_traffic(async_sandbox_factory):
+ async_sandbox = await async_sandbox_factory(
+ secure=True, network={"allow_public_traffic": False}
+ )
+ contexts = await async_sandbox.list_code_contexts()
+
+ # default contexts should include python and javascript
+ languages = [context.language for context in contexts]
+ assert "python" in languages
+ assert "javascript" in languages
+
+
+@pytest.mark.skip_debug
+async def test_restart_context_secure_traffic(async_sandbox_factory):
+ async_sandbox = await async_sandbox_factory(
+ secure=True, network={"allow_public_traffic": False}
+ )
+ context = await async_sandbox.create_code_context()
+
+ # set a variable in the context
+ await async_sandbox.run_code("x = 1", context=context)
+
+ # restart the context
+ await async_sandbox.restart_code_context(context.id)
+
+ # check that the variable no longer exists
+ execution = await async_sandbox.run_code("x", context=context)
+
+ # check for a NameError with message "name 'x' is not defined"
+ assert execution.error is not None
+ assert execution.error.name == "NameError"
+ assert execution.error.value == "name 'x' is not defined"
diff --git a/python/tests/async/test_async_custom_repr_object.py b/python/tests/async/test_async_custom_repr_object.py
new file mode 100644
index 00000000..7b35e925
--- /dev/null
+++ b/python/tests/async/test_async_custom_repr_object.py
@@ -0,0 +1,12 @@
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+
+code = """
+from IPython.display import display
+
+display({'text/latex': r'\text{CustomReprObject}'}, raw=True)
+"""
+
+
+async def test_bash(async_sandbox: AsyncSandbox):
+ execution = await async_sandbox.run_code(code)
+ assert execution.results[0].formats() == ["latex"]
diff --git a/python/tests/async/test_async_cwd.py b/python/tests/async/test_async_cwd.py
new file mode 100644
index 00000000..1896d767
--- /dev/null
+++ b/python/tests/async/test_async_cwd.py
@@ -0,0 +1,41 @@
+import pytest
+
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+
+
+@pytest.mark.skip_debug()
+async def test_cwd_python(async_sandbox: AsyncSandbox):
+ result = await async_sandbox.run_code("from pathlib import Path; print(Path.cwd())")
+ assert "".join(result.logs.stdout).strip() == "/home/user"
+
+
+@pytest.mark.skip_debug()
+async def test_cwd_javascript(async_sandbox: AsyncSandbox):
+ result = await async_sandbox.run_code("process.cwd()", language="js")
+ assert result.text == "/home/user"
+
+
+@pytest.mark.skip_debug()
+async def test_cwd_typescript(async_sandbox: AsyncSandbox):
+ result = await async_sandbox.run_code("process.cwd()", language="ts")
+ assert result.text == "/home/user"
+
+
+@pytest.mark.skip_debug()
+async def test_cwd_r(async_sandbox: AsyncSandbox):
+ result = await async_sandbox.run_code("getwd()", language="r")
+ assert result.results[0].text.strip() == '[1] "/home/user"'
+
+
+@pytest.mark.skip_debug()
+async def test_cwd_java(async_sandbox: AsyncSandbox):
+ result = await async_sandbox.run_code(
+ 'System.getProperty("user.dir")', language="java"
+ )
+ assert result.results[0].text.strip() == "/home/user"
+
+
+@pytest.mark.skip_debug()
+async def test_cwd_bash(async_sandbox: AsyncSandbox):
+ result = await async_sandbox.run_code("pwd", language="bash")
+ assert "".join(result.logs.stdout).strip() == "/home/user"
diff --git a/python/tests/async/test_async_data.py b/python/tests/async/test_async_data.py
new file mode 100644
index 00000000..d11a67b8
--- /dev/null
+++ b/python/tests/async/test_async_data.py
@@ -0,0 +1,17 @@
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+
+
+async def test_data(async_sandbox: AsyncSandbox):
+ # plot random chart
+ result = await async_sandbox.run_code(
+ """
+ import pandas as pd
+ pd.DataFrame({"a": [1, 2, 3]})
+ """
+ )
+
+ # there's your image
+ data = result.results[0]
+ assert data.data
+ assert "a" in data.data
+ assert len(data.data["a"]) == 3
diff --git a/python/tests/async/test_async_default_kernels.py b/python/tests/async/test_async_default_kernels.py
new file mode 100644
index 00000000..b2df1dca
--- /dev/null
+++ b/python/tests/async/test_async_default_kernels.py
@@ -0,0 +1,36 @@
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+
+
+async def test_js_kernel(async_sandbox: AsyncSandbox):
+ execution = await async_sandbox.run_code(
+ "console.log('Hello, World!')", language="js"
+ )
+ assert execution.logs.stdout == ["Hello, World!\n"]
+
+
+async def test_js_esm_imports(async_sandbox: AsyncSandbox):
+ execution = await async_sandbox.run_code(
+ """
+ import { readFileSync } from 'fs'
+ console.log(typeof readFileSync)
+ """,
+ language="js",
+ )
+ assert execution.logs.stdout == ["function\n"]
+
+
+async def test_js_top_level_await(async_sandbox: AsyncSandbox):
+ execution = await async_sandbox.run_code(
+ """
+ await Promise.resolve('Hello World!')
+ """,
+ language="js",
+ )
+ assert execution.text == "Hello World!"
+
+
+async def test_ts_kernel(async_sandbox: AsyncSandbox):
+ execution = await async_sandbox.run_code(
+ "const message: string = 'Hello, World!'; console.log(message);", language="ts"
+ )
+ assert execution.logs.stdout == ["Hello, World!\n"]
diff --git a/python/tests/async/test_async_display_data.py b/python/tests/async/test_async_display_data.py
new file mode 100644
index 00000000..bb50647f
--- /dev/null
+++ b/python/tests/async/test_async_display_data.py
@@ -0,0 +1,23 @@
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+
+
+async def test_display_data(async_sandbox: AsyncSandbox):
+ # plot random chart
+ result = await async_sandbox.run_code(
+ """
+ import matplotlib.pyplot as plt
+ import numpy as np
+
+ x = np.linspace(0, 20, 100)
+ y = np.sin(x)
+
+ plt.plot(x, y)
+ plt.show()
+ """
+ )
+
+ # there's your image
+ data = result.results[0]
+ assert data.png
+ assert data.text
+ assert not data.extra
diff --git a/python/tests/async/test_async_execution_count.py b/python/tests/async/test_async_execution_count.py
new file mode 100644
index 00000000..c4955838
--- /dev/null
+++ b/python/tests/async/test_async_execution_count.py
@@ -0,0 +1,10 @@
+import pytest
+
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+
+
+@pytest.mark.skip_debug()
+async def test_execution_count(async_sandbox: AsyncSandbox):
+ await async_sandbox.run_code("echo 'E2B is awesome!'")
+ result = await async_sandbox.run_code("!pwd")
+ assert result.execution_count == 2
diff --git a/python/tests/async/test_async_interrupt.py b/python/tests/async/test_async_interrupt.py
new file mode 100644
index 00000000..ad8a9a0e
--- /dev/null
+++ b/python/tests/async/test_async_interrupt.py
@@ -0,0 +1,25 @@
+import asyncio
+
+import pytest
+
+from e2b import TimeoutException
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+
+
+async def test_subsequent_execution_works_after_client_timeout(
+ async_sandbox: AsyncSandbox,
+):
+ # Start a long-running execution with a short timeout.
+ # This simulates a client disconnect: the SDK closes the connection,
+ # which should trigger the server to interrupt the kernel (#213).
+ with pytest.raises(TimeoutException):
+ await async_sandbox.run_code("import time; time.sleep(300)", timeout=3)
+
+ # Wait for the server to detect the disconnect (via keepalive write
+ # failure) and interrupt the kernel.
+ await asyncio.sleep(5)
+
+ # Run a simple execution. Without the kernel interrupt fix, this would
+ # block behind the still-running sleep(30) and time out.
+ result = await async_sandbox.run_code("1 + 1", timeout=10)
+ assert result.text == "2"
diff --git a/python/tests/async/test_async_kernels.py b/python/tests/async/test_async_kernels.py
new file mode 100644
index 00000000..ce88967b
--- /dev/null
+++ b/python/tests/async/test_async_kernels.py
@@ -0,0 +1,25 @@
+import pytest
+from e2b import InvalidArgumentException
+
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+
+
+async def test_create_new_kernel(async_sandbox: AsyncSandbox):
+ await async_sandbox.create_code_context()
+
+
+async def test_independence_of_kernels(async_sandbox: AsyncSandbox):
+ context = await async_sandbox.create_code_context()
+ await async_sandbox.run_code("x = 1")
+
+ r = await async_sandbox.run_code("x", context=context)
+ assert r.error is not None
+ assert r.error.value == "name 'x' is not defined"
+
+
+async def test_pass_context_and_language(async_sandbox: AsyncSandbox):
+ context = await async_sandbox.create_code_context(language="python")
+ with pytest.raises(InvalidArgumentException):
+ await async_sandbox.run_code(
+ "console.log('Hello, World!')", language="js", context=context
+ )
diff --git a/python/tests/async/test_async_reconnect.py b/python/tests/async/test_async_reconnect.py
new file mode 100644
index 00000000..6cd36c83
--- /dev/null
+++ b/python/tests/async/test_async_reconnect.py
@@ -0,0 +1,12 @@
+import pytest
+
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+
+
+@pytest.mark.skip_debug
+async def test_reconnect(async_sandbox: AsyncSandbox):
+ sandbox_id = async_sandbox.sandbox_id
+
+ sandbox2 = await AsyncSandbox.connect(sandbox_id)
+ result = await sandbox2.run_code("x =1; x")
+ assert result.text == "1"
diff --git a/python/tests/async/test_async_statefulness.py b/python/tests/async/test_async_statefulness.py
new file mode 100644
index 00000000..e33dd808
--- /dev/null
+++ b/python/tests/async/test_async_statefulness.py
@@ -0,0 +1,8 @@
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+
+
+async def test_stateful(async_sandbox: AsyncSandbox):
+ await async_sandbox.run_code("async_test_stateful = 1")
+
+ result = await async_sandbox.run_code("async_test_stateful+=1; async_test_stateful")
+ assert result.text == "2"
diff --git a/python/tests/async/test_async_streaming.py b/python/tests/async/test_async_streaming.py
new file mode 100644
index 00000000..ceb5c851
--- /dev/null
+++ b/python/tests/async/test_async_streaming.py
@@ -0,0 +1,45 @@
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+
+
+async def test_streaming_output(async_sandbox: AsyncSandbox):
+ out = []
+
+ def test(line) -> None:
+ out.append(line)
+ return
+
+ await async_sandbox.run_code("print(1)", on_stdout=test)
+
+ assert len(out) == 1
+ assert out[0].line == "1\n"
+
+
+async def test_streaming_error(async_sandbox: AsyncSandbox):
+ out = []
+
+ await async_sandbox.run_code(
+ "import sys;print(1, file=sys.stderr)", on_stderr=out.append
+ )
+
+ assert len(out) == 1
+ assert out[0].line == "1\n"
+
+
+async def test_streaming_result(async_sandbox: AsyncSandbox):
+ code = """
+ import matplotlib.pyplot as plt
+ import numpy as np
+
+ x = np.linspace(0, 20, 100)
+ y = np.sin(x)
+
+ plt.plot(x, y)
+ plt.show()
+
+ x
+ """
+
+ out = []
+ await async_sandbox.run_code(code, on_result=out.append)
+
+ assert len(out) == 2
diff --git a/python/tests/async/test_async_systemd.py b/python/tests/async/test_async_systemd.py
new file mode 100644
index 00000000..5a129abc
--- /dev/null
+++ b/python/tests/async/test_async_systemd.py
@@ -0,0 +1,63 @@
+import asyncio
+
+import pytest
+
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+
+
+async def wait_for_health(sandbox: AsyncSandbox, max_retries=10, interval_ms=100):
+ for _ in range(max_retries):
+ try:
+ result = await sandbox.commands.run(
+ 'curl -s -o /dev/null -w "%{http_code}" http://0.0.0.0:49999/health'
+ )
+ if result.stdout.strip() == "200":
+ return True
+ except Exception:
+ pass
+ await asyncio.sleep(interval_ms / 1000)
+ return False
+
+
+@pytest.mark.skip_debug
+async def test_restart_after_jupyter_kill(async_sandbox: AsyncSandbox):
+ # Verify health is up initially
+ assert await wait_for_health(async_sandbox)
+
+ # Kill the jupyter process as root
+ # The command handle may get killed too (killing jupyter cascades to code-interpreter),
+ # so we catch the error.
+ try:
+ await async_sandbox.commands.run(
+ "kill -9 $(pgrep -f 'jupyter server')", user="root"
+ )
+ except Exception:
+ pass
+
+ # Wait for systemd to restart both services
+ assert await wait_for_health(async_sandbox, 60, 500)
+
+ # Verify code execution works after recovery
+ result = await async_sandbox.run_code("x = 1; x")
+ assert result.text == "1"
+
+
+@pytest.mark.skip_debug
+async def test_restart_after_code_interpreter_kill(async_sandbox: AsyncSandbox):
+ # Verify health is up initially
+ assert await wait_for_health(async_sandbox)
+
+ # Kill the code-interpreter process as root
+ try:
+ await async_sandbox.commands.run(
+ "kill -9 $(pgrep -f 'uvicorn main:app')", user="root"
+ )
+ except Exception:
+ pass
+
+ # Wait for systemd to restart it and health to come back
+ assert await wait_for_health(async_sandbox, 60, 500)
+
+ # Verify code execution works after recovery
+ result = await async_sandbox.run_code("x = 1; x")
+ assert result.text == "1"
diff --git a/python/tests/benchmarking.py b/python/tests/benchmarking.py
deleted file mode 100644
index 14220fee..00000000
--- a/python/tests/benchmarking.py
+++ /dev/null
@@ -1,33 +0,0 @@
-import time
-
-from dotenv import load_dotenv
-
-from e2b_code_interpreter.main import CodeInterpreter
-
-load_dotenv()
-
-iterations = 10
-create_sandbox_time = 0
-first_exec_time = 0
-second_exec_time = 0
-
-for i in range(iterations):
- print("Iteration:", i + 1)
- start_time = time.time()
- sandbox = CodeInterpreter()
- create_sandbox_time += time.time() - start_time
-
- start_time = time.time()
- sandbox.notebook.exec_cell("x = 1")
- first_exec_time += time.time() - start_time
-
- start_time = time.time()
- result = sandbox.notebook.exec_cell("x+=1; x")
- second_exec_time += time.time() - start_time
-
- sandbox.close()
-
-
-print(f"Average Create Sandbox Time: {create_sandbox_time / iterations}s")
-print(f"Average Execute Python x = 1 Time: {first_exec_time / iterations}s")
-print(f"Average Execute Python x+=1; x Time: {second_exec_time / iterations}s")
diff --git a/python/tests/charts/test_bar.py b/python/tests/charts/test_bar.py
new file mode 100644
index 00000000..a35b19c1
--- /dev/null
+++ b/python/tests/charts/test_bar.py
@@ -0,0 +1,50 @@
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+from e2b_code_interpreter.charts import ChartType, BarChart
+
+code = """
+import matplotlib.pyplot as plt
+
+# Prepare data
+authors = ['Author A', 'Author B', 'Author C', 'Author D']
+sales = [100, 200, 300, 400]
+
+# Create and customize the bar chart
+plt.figure(figsize=(10, 6))
+plt.bar(authors, sales, label='Books Sold', color='blue')
+plt.xlabel('Authors')
+plt.ylabel('Number of Books Sold')
+plt.title('Book Sales by Authors')
+
+# Display the chart
+plt.tight_layout()
+plt.show()
+"""
+
+
+async def test_chart_bar(async_sandbox: AsyncSandbox):
+ result = await async_sandbox.run_code(code)
+
+ chart = result.results[0].chart
+ assert chart
+
+ assert isinstance(chart, BarChart)
+ assert chart.type == ChartType.BAR
+ assert chart.title == "Book Sales by Authors"
+
+ assert chart.x_label == "Authors"
+ assert chart.y_label == "Number of Books Sold"
+
+ assert chart.x_unit is None
+ assert chart.y_unit is None
+
+ bars = chart.elements
+ assert len(bars) == 4
+
+ assert [bar.value for bar in bars] == [100, 200, 300, 400]
+ assert [bar.label for bar in bars] == [
+ "Author A",
+ "Author B",
+ "Author C",
+ "Author D",
+ ]
+ assert [bar.group for bar in bars] == ["Books Sold"] * 4
diff --git a/python/tests/charts/test_box_and_whiskers.py b/python/tests/charts/test_box_and_whiskers.py
new file mode 100644
index 00000000..4328faf6
--- /dev/null
+++ b/python/tests/charts/test_box_and_whiskers.py
@@ -0,0 +1,60 @@
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+from e2b_code_interpreter.charts import BoxAndWhiskerChart, ChartType
+
+code = """
+import matplotlib.pyplot as plt
+import numpy as np
+
+# Sample data
+data = {
+ 'Class A': [85, 90, 78, 92, 88],
+ 'Class B': [95, 89, 76, 91, 84, 87],
+ 'Class C': [75, 82, 88, 79, 86]
+}
+
+# Create figure and axis
+fig, ax = plt.subplots(figsize=(10, 6))
+
+# Customize plot
+ax.set_title('Exam Scores Distribution')
+ax.set_xlabel('Class')
+ax.set_ylabel('Score')
+
+# Set custom colors
+ax.boxplot(data.values(), labels=data.keys(), patch_artist=True)
+
+# Add legend
+ax.legend()
+
+# Adjust layout and show plot
+plt.tight_layout()
+plt.show()
+"""
+
+
+async def test_box_and_whiskers(async_sandbox: AsyncSandbox):
+ result = await async_sandbox.run_code(code)
+
+ chart = result.results[0].chart
+ assert chart
+
+ assert isinstance(chart, BoxAndWhiskerChart)
+ assert chart.type == ChartType.BOX_AND_WHISKER
+ assert chart.title == "Exam Scores Distribution"
+
+ assert chart.x_label == "Class"
+ assert chart.y_label == "Score"
+
+ assert chart.x_unit is None
+ assert chart.y_unit is None
+
+ bars = chart.elements
+ assert len(bars) == 3
+
+ assert [bar.outliers for bar in bars] == [[], [76], []]
+ assert [bar.min for bar in bars] == [78, 84, 75]
+ assert [bar.first_quartile for bar in bars] == [85, 84.75, 79]
+ assert [bar.median for bar in bars] == [88, 88, 82]
+ assert [bar.third_quartile for bar in bars] == [90, 90.5, 86]
+ assert [bar.max for bar in bars] == [92, 95, 88]
+ assert [bar.label for bar in bars] == ["Class A", "Class B", "Class C"]
diff --git a/python/tests/charts/test_json.py b/python/tests/charts/test_json.py
new file mode 100644
index 00000000..f0dbb189
--- /dev/null
+++ b/python/tests/charts/test_json.py
@@ -0,0 +1,27 @@
+import json
+
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+
+code = """
+import matplotlib.pyplot as plt
+import numpy as np
+
+# Create data
+N = 5
+x = np.random.rand(N)
+y = np.random.rand(N)
+
+plt.xlabel("A")
+
+plt.scatter(x, y, c='blue', label='Dataset')
+
+plt.show()
+"""
+
+
+async def test_scatter_chart(async_sandbox: AsyncSandbox):
+ result = await async_sandbox.run_code(code)
+ serialized = result.to_json()
+ assert isinstance(serialized, str)
+
+ assert json.loads(serialized)["results"][0]["chart"]["type"] == "scatter"
diff --git a/python/tests/charts/test_line.py b/python/tests/charts/test_line.py
new file mode 100644
index 00000000..e90b4bd3
--- /dev/null
+++ b/python/tests/charts/test_line.py
@@ -0,0 +1,76 @@
+import datetime
+
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+from e2b_code_interpreter.charts import LineChart
+
+code = """
+import numpy as np
+import matplotlib.pyplot as plt
+import datetime
+
+# Generate x values
+dates = [datetime.date(2023, 9, 1) + datetime.timedelta(seconds=i) for i in range(100)]
+
+x = np.linspace(0, 2*np.pi, 100)
+# Calculate y values
+y_sin = np.sin(x)
+y_cos = np.cos(x)
+
+# Create the plot
+plt.figure(figsize=(10, 6))
+plt.plot(dates, y_sin, label='sin(x)')
+plt.plot(dates, y_cos, label='cos(x)')
+
+# Add labels and title
+plt.xlabel("Time (s)")
+plt.ylabel("Amplitude (Hz)")
+plt.title('Plot of sin(x) and cos(x)')
+
+# Display the plot
+plt.show()
+"""
+
+
+async def test_line_chart(async_sandbox: AsyncSandbox):
+ result = await async_sandbox.run_code(code)
+
+ chart = result.results[0].chart
+ assert chart
+
+ assert isinstance(chart, LineChart)
+ assert chart.title == "Plot of sin(x) and cos(x)"
+
+ assert chart.x_label == "Time (s)"
+ assert chart.y_label == "Amplitude (Hz)"
+
+ assert chart.x_unit == "s"
+ assert chart.y_unit == "Hz"
+
+ assert chart.x_scale == "datetime"
+ assert chart.y_scale == "linear"
+
+ assert all(isinstance(x, str) for x in chart.x_ticks)
+ parsed_date = datetime.datetime.fromisoformat(chart.x_ticks[0])
+ assert isinstance(parsed_date, datetime.datetime)
+ assert all(isinstance(y, float) for y in chart.y_ticks)
+
+ assert all(isinstance(x, str) for x in chart.y_tick_labels)
+ assert all(isinstance(y, str) for y in chart.y_tick_labels)
+
+ lines = chart.elements
+ assert len(lines) == 2
+
+ first_line = lines[0]
+ assert first_line.label == "sin(x)"
+ assert len(first_line.points) == 100
+ assert all(isinstance(point, tuple) for point in first_line.points)
+ assert all(
+ isinstance(x, str) and isinstance(y, float) for x, y in first_line.points
+ )
+
+ parsed_date = datetime.datetime.fromisoformat(first_line.points[0][0])
+ assert isinstance(parsed_date, datetime.datetime)
+
+ second_line = lines[1]
+ assert second_line.label == "cos(x)"
+ assert len(second_line.points) == 100
diff --git a/python/tests/charts/test_log_chart.py b/python/tests/charts/test_log_chart.py
new file mode 100644
index 00000000..e74c9ec5
--- /dev/null
+++ b/python/tests/charts/test_log_chart.py
@@ -0,0 +1,64 @@
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+from e2b_code_interpreter.charts import LineChart
+
+# Log chart
+code = """
+import numpy as np
+import matplotlib.pyplot as plt
+
+# Generate x values
+x = np.linspace(0, 100, 100)
+# Calculate y values
+y = np.exp(x)
+
+# Create the plot
+plt.figure(figsize=(10, 6))
+plt.plot(x, y, label='y = e^x')
+
+# Set log scale for the y-axis
+plt.yscale('log')
+
+# Add labels and title
+plt.xlabel('X-axis')
+plt.ylabel('Y-axis (log scale)')
+plt.title('Chart with Log Scale on Y-axis')
+
+plt.legend()
+plt.grid(True)
+plt.show()
+"""
+
+
+async def test_log_chart(async_sandbox: AsyncSandbox):
+ result = await async_sandbox.run_code(code)
+
+ chart = result.results[0].chart
+ assert chart
+
+ assert isinstance(chart, LineChart)
+ assert chart.title == "Chart with Log Scale on Y-axis"
+
+ assert chart.x_label == "X-axis"
+ assert chart.y_label == "Y-axis (log scale)"
+
+ assert chart.x_unit is None
+ assert chart.y_unit == "log scale"
+
+ assert chart.x_scale == "linear"
+ assert chart.y_scale == "log"
+
+ assert all(isinstance(x, float) for x in chart.x_ticks)
+ assert all(isinstance(y, float) for y in chart.y_ticks)
+
+ assert all(isinstance(x, str) for x in chart.x_tick_labels)
+ assert all(isinstance(y, str) for y in chart.y_tick_labels)
+
+ lines = chart.elements
+ assert len(lines) == 1
+
+ line = lines[0]
+ assert line.label == "y = e^x"
+ assert len(line.points) == 100
+
+ assert all(isinstance(x, tuple) for x in line.points)
+ assert all(isinstance(x, float) and isinstance(y, float) for x, y in line.points)
diff --git a/python/tests/charts/test_pie.py b/python/tests/charts/test_pie.py
new file mode 100644
index 00000000..f6ffefeb
--- /dev/null
+++ b/python/tests/charts/test_pie.py
@@ -0,0 +1,50 @@
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+from e2b_code_interpreter.charts import PieChart
+
+code = """
+import matplotlib.pyplot as plt
+import numpy as np
+
+# Step 1: Define the data for the pie chart
+categories = ["No", "No, in blue"]
+sizes = [90, 10]
+
+# Step 2: Create the figure and axis objects
+fig, ax = plt.subplots(figsize=(8, 8))
+
+plt.xlabel("x")
+plt.ylabel("y")
+
+# Step 3: Create the pie chart
+ax.pie(sizes, labels=categories, autopct='%1.1f%%', startangle=90, colors=plt.cm.Pastel1.colors[:len(categories)])
+
+# Step 4: Add title and legend
+ax.axis('equal') # Equal aspect ratio ensures that pie is drawn as a circle
+plt.title('Will I wake up early tomorrow?')
+
+# Step 5: Show the plot
+plt.show()
+"""
+
+
+async def test_pie_chart(async_sandbox: AsyncSandbox):
+ result = await async_sandbox.run_code(code)
+
+ chart = result.results[0].chart
+ assert chart
+
+ assert isinstance(chart, PieChart)
+
+ assert chart.title == "Will I wake up early tomorrow?"
+
+ assert len(chart.elements) == 2
+
+ first_data = chart.elements[0]
+ assert first_data.label == "No"
+ assert first_data.angle == 324
+ assert first_data.radius == 1
+
+ second_data = chart.elements[1]
+ assert second_data.label == "No, in blue"
+ assert second_data.angle == 36
+ assert second_data.radius == 1
diff --git a/python/tests/charts/test_scale.py b/python/tests/charts/test_scale.py
new file mode 100644
index 00000000..221ef04e
--- /dev/null
+++ b/python/tests/charts/test_scale.py
@@ -0,0 +1,52 @@
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+from e2b_code_interpreter.charts import LineChart
+
+
+async def test_datetime_scale(async_sandbox: AsyncSandbox):
+ code = """
+ import numpy as np
+ import matplotlib.pyplot as plt
+ import datetime
+
+ # Generate x values
+ dates = [datetime.date(2023, 9, 1) + datetime.timedelta(seconds=i) for i in range(100)]
+ y_sin = np.sin(np.linspace(0, 2*np.pi, 100))
+
+ # Create the plot
+ plt.figure(figsize=(10, 6))
+ plt.plot(dates, y_sin, label='sin(x)')
+ plt.show()
+ """
+
+ result = await async_sandbox.run_code(code)
+
+ chart = result.results[0].chart
+ assert chart
+
+ assert isinstance(chart, LineChart)
+ assert chart.x_scale == "datetime"
+ assert chart.y_scale == "linear"
+
+
+async def test_categorical_scale(async_sandbox: AsyncSandbox):
+ code = """
+ import numpy as np
+ import matplotlib.pyplot as plt
+
+ x = [1, 2, 3, 4, 5]
+ y = ['A', 'B', 'C', 'D', 'E']
+
+ # Create the plot
+ plt.figure(figsize=(10, 6))
+ plt.plot(x, y)
+ plt.show()
+ """
+
+ result = await async_sandbox.run_code(code)
+
+ chart = result.results[0].chart
+ assert chart
+
+ assert isinstance(chart, LineChart)
+ assert chart.x_scale == "linear"
+ assert chart.y_scale == "categorical"
diff --git a/python/tests/charts/test_scatter.py b/python/tests/charts/test_scatter.py
new file mode 100644
index 00000000..1668f4cc
--- /dev/null
+++ b/python/tests/charts/test_scatter.py
@@ -0,0 +1,57 @@
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+from e2b_code_interpreter.charts import ScatterChart
+
+code = """
+import matplotlib.pyplot as plt
+import numpy as np
+
+# Create data
+N = 5
+x1 = np.random.rand(N)
+y1 = np.random.rand(N)
+x2 = np.random.rand(2*N)
+y2 = np.random.rand(2*N)
+
+plt.xlabel("A")
+plt.ylabel("B")
+
+plt.scatter(x1, y1, c='blue', label='Dataset 1')
+plt.scatter(x2, y2, c='red', label='Dataset 2')
+
+plt.show()
+"""
+
+
+async def test_scatter_chart(async_sandbox: AsyncSandbox):
+ result = await async_sandbox.run_code(code)
+
+ chart = result.results[0].chart
+ assert chart
+
+ assert isinstance(chart, ScatterChart)
+
+ assert chart.title is None
+ assert chart.x_label == "A"
+ assert chart.y_label == "B"
+
+ assert chart.x_scale == "linear"
+ assert chart.y_scale == "linear"
+
+ assert all(isinstance(x, float) for x in chart.x_ticks)
+ assert all(isinstance(y, float) for y in chart.y_ticks)
+
+ assert all(isinstance(x, str) for x in chart.y_tick_labels)
+ assert all(isinstance(y, str) for y in chart.y_tick_labels)
+
+ assert len(chart.elements) == 2
+
+ first_data = chart.elements[0]
+ assert first_data.label == "Dataset 1"
+ assert len(first_data.points) == 5
+ print(first_data.points)
+ assert all(isinstance(x, tuple) for x in first_data.points)
+
+ second_data = chart.elements[1]
+ assert second_data.label == "Dataset 2"
+ assert len(second_data.points) == 10
+ assert all(isinstance(x, tuple) for x in second_data.points)
diff --git a/python/tests/charts/test_superchart.py b/python/tests/charts/test_superchart.py
new file mode 100644
index 00000000..ee2e324e
--- /dev/null
+++ b/python/tests/charts/test_superchart.py
@@ -0,0 +1,61 @@
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+from e2b_code_interpreter.charts import ChartType, SuperChart, LineChart, ScatterChart
+
+code = """
+import matplotlib.pyplot as plt
+import numpy as np
+
+# Data for plotting
+x1 = np.linspace(0, 10, 100)
+y1 = np.sin(x1)
+
+# Create a figure with multiple subplots
+fig, axs = plt.subplots(1, 2, figsize=(10, 8))
+fig.suptitle('Multiple Charts Example', fontsize=16)
+
+# Plotting on the different axes
+axs[0].plot(x1, y1, 'r')
+axs[0].set_title('Sine Wave')
+axs[0].grid(True)
+
+N = 5
+x2 = np.random.rand(N)
+y2 = np.random.rand(N)
+
+axs[1].scatter(x2, y2, c='blue', label='Dataset 1')
+axs[1].set_xlabel('X')
+axs[1].set_ylabel('Y')
+axs[1].set_title('Scatter Plot')
+axs[1].grid(True)
+
+plt.show()
+"""
+
+
+async def test_super_chart(async_sandbox: AsyncSandbox):
+ result = await async_sandbox.run_code(code)
+ chart = result.results[0].chart
+ assert chart
+
+ assert isinstance(chart, SuperChart)
+ assert chart.type == ChartType.SUPERCHART
+ assert chart.title == "Multiple Charts Example"
+
+ charts = chart.elements
+ assert len(charts) == 2
+
+ first_chart = charts[0]
+ assert first_chart.title == "Sine Wave"
+ assert isinstance(first_chart, LineChart)
+ assert first_chart.x_label is None
+ assert first_chart.y_label is None
+ assert len(first_chart.elements) == 1
+ assert len(first_chart.elements[0].points) == 100
+
+ second_chart = charts[1]
+ assert second_chart.title == "Scatter Plot"
+ assert isinstance(second_chart, ScatterChart)
+ assert second_chart.x_label == "X"
+ assert second_chart.y_label == "Y"
+ assert len(second_chart.elements) == 1
+ assert len(second_chart.elements[0].points) == 5
diff --git a/python/tests/charts/test_unknown.py b/python/tests/charts/test_unknown.py
new file mode 100644
index 00000000..87ca36b3
--- /dev/null
+++ b/python/tests/charts/test_unknown.py
@@ -0,0 +1,40 @@
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+from e2b_code_interpreter.charts import ChartType, Chart
+
+code = """
+import matplotlib.pyplot as plt
+import numpy as np
+
+# Create a figure and an axis
+fig, ax = plt.subplots()
+
+# Create data for two concentric circles
+circle1 = plt.Circle((0, 0), 1, color='blue', fill=False, linewidth=2)
+circle2 = plt.Circle((0, 0), 2, color='red', fill=False, linewidth=2)
+
+# Add the circles to the axes
+ax.add_artist(circle1)
+ax.add_artist(circle2)
+
+# Set grid
+ax.grid(True)
+
+# Set title
+plt.title('Two Concentric Circles')
+
+# Show the plot
+plt.show()
+"""
+
+
+async def test_unknown_charts(async_sandbox: AsyncSandbox):
+ result = await async_sandbox.run_code(code)
+
+ chart = result.results[0].chart
+ assert chart
+
+ assert isinstance(chart, Chart)
+ assert chart.type == ChartType.UNKNOWN
+ assert chart.title == "Two Concentric Circles"
+
+ assert len(chart.elements) == 0
diff --git a/python/tests/conftest.py b/python/tests/conftest.py
new file mode 100644
index 00000000..199b0a12
--- /dev/null
+++ b/python/tests/conftest.py
@@ -0,0 +1,81 @@
+import asyncio
+import os
+
+import pytest
+
+from e2b_code_interpreter import (
+ AsyncSandbox,
+ Sandbox,
+)
+import uuid
+
+
+@pytest.fixture(scope="session")
+def sandbox_test_id():
+ return f"test_{uuid.uuid4()}"
+
+
+@pytest.fixture()
+def template():
+ return os.getenv("E2B_TESTS_TEMPLATE") or "code-interpreter-v1"
+
+
+@pytest.fixture()
+def sandbox_factory(request, template, sandbox_test_id):
+ def factory(*, template_name: str = template, **kwargs):
+ kwargs.setdefault("secure", False)
+ kwargs.setdefault("timeout", 60)
+
+ metadata = kwargs.setdefault("metadata", dict())
+ metadata.setdefault("sandbox_test_id", sandbox_test_id)
+
+ sandbox = Sandbox.create(template_name, **kwargs)
+
+ request.addfinalizer(lambda: sandbox.kill())
+
+ return sandbox
+
+ return factory
+
+
+@pytest.fixture()
+def sandbox(sandbox_factory):
+ return sandbox_factory()
+
+
+@pytest.fixture
+async def async_sandbox_factory(template, sandbox_test_id):
+ sandboxes: list[AsyncSandbox] = []
+
+ async def factory(*, template_name: str = template, **kwargs):
+ kwargs.setdefault("timeout", 60)
+
+ metadata = kwargs.setdefault("metadata", dict())
+ metadata.setdefault("sandbox_test_id", sandbox_test_id)
+
+ sandbox = await AsyncSandbox.create(template_name, **kwargs)
+ sandboxes.append(sandbox)
+ return sandbox
+
+ yield factory
+
+ await asyncio.gather(
+ *(sandbox.kill() for sandbox in sandboxes), return_exceptions=True
+ )
+
+
+@pytest.fixture
+async def async_sandbox(async_sandbox_factory):
+ return await async_sandbox_factory()
+
+
+@pytest.fixture
+def debug():
+ return os.getenv("E2B_DEBUG") is not None
+
+
+@pytest.fixture(autouse=True)
+def skip_by_debug(request, debug):
+ if request.node.get_closest_marker("skip_debug"):
+ if debug:
+ pytest.skip("skipped because E2B_DEBUG is set")
diff --git a/python/tests/images/test_images.py b/python/tests/images/test_images.py
new file mode 100644
index 00000000..46c45f5e
--- /dev/null
+++ b/python/tests/images/test_images.py
@@ -0,0 +1,53 @@
+from e2b_code_interpreter.code_interpreter_async import AsyncSandbox
+
+
+async def test_show_image(async_sandbox: AsyncSandbox):
+ code = """
+ import numpy
+ from PIL import Image
+
+ imarray = numpy.random.rand(16,16,3) * 255
+ image = Image.fromarray(imarray.astype('uint8')).convert('RGBA')
+
+ image.show()
+ print("Image shown.")
+ """
+
+ execution = await async_sandbox.run_code(code)
+
+ image = execution.results[0].png
+ assert image
+
+
+async def test_image_as_last_command(async_sandbox: AsyncSandbox):
+ code = """
+ import numpy
+ from PIL import Image
+
+ imarray = numpy.random.rand(16,16,3) * 255
+ image = Image.fromarray(imarray.astype('uint8')).convert('RGBA')
+
+ image
+ """
+ execution = await async_sandbox.run_code(code)
+
+ image = execution.results[0].png
+ assert image
+
+
+async def test_get_image_on_save(async_sandbox: AsyncSandbox):
+ code = """
+ import numpy
+ from PIL import Image
+
+ imarray = numpy.random.rand(16,16,3) * 255
+ image = Image.fromarray(imarray.astype('uint8')).convert('RGBA')
+
+ image.save("test.png")
+ print("Image saved.")
+ """
+
+ execution = await async_sandbox.run_code(code)
+
+ image = execution.results[0].png
+ assert image
diff --git a/python/tests/performance.py b/python/tests/performance.py
new file mode 100644
index 00000000..dbaf99ac
--- /dev/null
+++ b/python/tests/performance.py
@@ -0,0 +1,205 @@
+from e2b_code_interpreter import Sandbox
+import time
+import os
+import statistics
+import matplotlib.pyplot as plt
+
+iterations_count = int(os.getenv("E2B_TESTS_BENCHMARK_ITERATIONS_COUNT", 20))
+template = os.getenv("E2B_TESTS_TEMPLATE", "code-interpreter-v1")
+
+# Lists to store metrics for each iteration
+sandbox_creation_times = []
+health_check_times = []
+first_code_run_times = []
+second_code_run_times = []
+
+for i in range(iterations_count):
+ print(f"\n--- Iteration {i + 1}/{iterations_count} ---")
+
+ start_time = time.time()
+ sbx = Sandbox.create(template=template)
+ end_time = time.time()
+ sandbox_creation_time = (end_time - start_time) * 1000
+ sandbox_creation_times.append(sandbox_creation_time)
+ print(f"Sandbox creation time: {sandbox_creation_time:.2f} milliseconds")
+
+ start_time = time.time()
+ sbx.commands.run("curl http://0.0.0.0:49999/health")
+ end_time = time.time()
+ health_check_time = (end_time - start_time) * 1000
+ health_check_times.append(health_check_time)
+ print(f"Health check time: {health_check_time:.2f} milliseconds")
+
+ start_time = time.time()
+ sbx.run_code("print('Hello, world!')")
+ end_time = time.time()
+ first_code_run_time = (end_time - start_time) * 1000
+ first_code_run_times.append(first_code_run_time)
+ print(f"First code run time: {first_code_run_time:.2f} milliseconds")
+
+ start_time = time.time()
+ sbx.run_code("print('Hello, world!')")
+ end_time = time.time()
+ second_code_run_time = (end_time - start_time) * 1000
+ second_code_run_times.append(second_code_run_time)
+ print(f"Second code run time: {second_code_run_time:.2f} milliseconds")
+
+ sbx.kill()
+
+
+# Calculate and print summary statistics
+def print_metric_summary(metric_name, times):
+ if not times:
+ return
+
+ low = min(times)
+ high = max(times)
+ mean = statistics.mean(times)
+ median = statistics.median(times)
+
+ print(f"\n{metric_name} Summary:")
+ print(f" Low: {low:.2f} ms")
+ print(f" High: {high:.2f} ms")
+ print(f" Mean: {mean:.2f} ms")
+ print(f" Median: {median:.2f} ms")
+
+
+print("\n" + "=" * 50)
+print("PERFORMANCE SUMMARY")
+print("=" * 50)
+
+print_metric_summary("Sandbox Creation Time", sandbox_creation_times)
+print_metric_summary("Health Check Time", health_check_times)
+print_metric_summary("First Code Run Time", first_code_run_times)
+print_metric_summary("Second Code Run Time", second_code_run_times)
+
+
+def create_performance_plot(
+ template,
+ iterations_count,
+ sandbox_creation_times,
+ health_check_times,
+ first_code_run_times,
+ second_code_run_times,
+):
+ """Create and save a performance visualization plot."""
+ print("\nGenerating performance plot...")
+ fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 10))
+
+ # Plot 1: All metrics over iterations
+ iterations = list(range(1, iterations_count + 1))
+ ax1.plot(
+ iterations,
+ sandbox_creation_times,
+ "b-o",
+ label="Sandbox Creation",
+ linewidth=1.5,
+ markersize=6,
+ markerfacecolor="blue",
+ markeredgecolor="darkblue",
+ markeredgewidth=1,
+ )
+ ax1.plot(
+ iterations,
+ health_check_times,
+ "g-s",
+ label="Health Check",
+ linewidth=1.5,
+ markersize=6,
+ markerfacecolor="green",
+ markeredgecolor="darkgreen",
+ markeredgewidth=1,
+ )
+ ax1.plot(
+ iterations,
+ first_code_run_times,
+ "r-^",
+ label="First Code Run",
+ linewidth=1.5,
+ markersize=6,
+ markerfacecolor="red",
+ markeredgecolor="darkred",
+ markeredgewidth=1,
+ )
+ ax1.plot(
+ iterations,
+ second_code_run_times,
+ "m-d",
+ label="Second Code Run",
+ linewidth=1.5,
+ markersize=6,
+ markerfacecolor="magenta",
+ markeredgecolor="darkmagenta",
+ markeredgewidth=1,
+ )
+
+ ax1.set_xlabel("Iteration")
+ ax1.set_ylabel("Time (ms)")
+ ax1.set_title(
+ f"Performance Metrics Over {iterations_count} Iterations - {template}"
+ )
+ ax1.legend()
+ ax1.grid(True, alpha=0.3)
+
+ # Set x-axis to show each iteration step
+ ax1.set_xticks(iterations)
+ ax1.set_xlim(0.5, iterations_count + 0.5)
+
+ # Plot 2: Box plot for distribution
+ all_metrics = [
+ sandbox_creation_times,
+ health_check_times,
+ first_code_run_times,
+ second_code_run_times,
+ ]
+ metric_names = [
+ "Sandbox\nCreation",
+ "Health\nCheck",
+ "First Code\nRun",
+ "Second Code\nRun",
+ ]
+
+ box_plot = ax2.boxplot(all_metrics, tick_labels=metric_names, patch_artist=True)
+ colors = ["lightblue", "lightgreen", "lightcoral", "plum"]
+ for patch, color in zip(box_plot["boxes"], colors):
+ patch.set_facecolor(color)
+
+ ax2.set_ylabel("Time (ms)")
+ ax2.set_title(f"Performance Distribution - {template}")
+ ax2.grid(True, alpha=0.3)
+
+ plt.tight_layout()
+
+ # Show summary statistics in the plot
+ stats_text = f"""Summary Statistics:
+Sandbox Creation: {statistics.mean(sandbox_creation_times):.1f}ms avg
+Health Check: {statistics.mean(health_check_times):.1f}ms avg
+First Code Run: {statistics.mean(first_code_run_times):.1f}ms avg
+Second Code Run: {statistics.mean(second_code_run_times):.1f}ms avg"""
+
+ fig.text(
+ 0.02,
+ 0.02,
+ stats_text,
+ fontsize=8,
+ verticalalignment="bottom",
+ bbox=dict(boxstyle="round", facecolor="wheat", alpha=0.8),
+ )
+
+ # Save the plot
+ plot_filename = "performance_plot.png"
+ plt.savefig(plot_filename, dpi=300, bbox_inches="tight")
+ print(f"Performance plot saved as: {plot_filename}")
+
+ return plot_filename
+
+
+# Create performance plot
+create_performance_plot(
+ template,
+ iterations_count,
+ sandbox_creation_times,
+ health_check_times,
+ first_code_run_times,
+ second_code_run_times,
+)
diff --git a/python/tests/sync/env_vars/test_bash.py b/python/tests/sync/env_vars/test_bash.py
new file mode 100644
index 00000000..9f5ea728
--- /dev/null
+++ b/python/tests/sync/env_vars/test_bash.py
@@ -0,0 +1,35 @@
+import pytest
+from e2b_code_interpreter import Sandbox
+
+
+@pytest.mark.skip_debug()
+def test_env_vars_on_sandbox(template):
+ sandbox = Sandbox.create(template=template, envs={"TEST_ENV_VAR": "supertest"})
+ try:
+ result = sandbox.run_code("echo $TEST_ENV_VAR", language="bash")
+ assert result.logs.stdout[0] == "supertest\n"
+ finally:
+ sandbox.kill()
+
+
+def test_env_vars_per_execution(sandbox: Sandbox):
+ result = sandbox.run_code("echo $FOO", envs={"FOO": "bar"}, language="bash")
+
+ result_empty = sandbox.run_code("echo ${FOO:-default}", language="bash")
+
+ assert result.logs.stdout[0] == "bar\n"
+ assert result_empty.logs.stdout[0] == "default\n"
+
+
+@pytest.mark.skip_debug()
+def test_env_vars_overwrite(template):
+ sandbox = Sandbox.create(template=template, envs={"TEST_ENV_VAR": "supertest"})
+ try:
+ result = sandbox.run_code(
+ "echo $TEST_ENV_VAR", language="bash", envs={"TEST_ENV_VAR": "overwrite"}
+ )
+ result_global_default = sandbox.run_code("echo $TEST_ENV_VAR", language="bash")
+ assert result.logs.stdout[0] == "overwrite\n"
+ assert result_global_default.logs.stdout[0] == "supertest\n"
+ finally:
+ sandbox.kill()
diff --git a/python/tests/sync/env_vars/test_java.py b/python/tests/sync/env_vars/test_java.py
new file mode 100644
index 00000000..b0950d9d
--- /dev/null
+++ b/python/tests/sync/env_vars/test_java.py
@@ -0,0 +1,51 @@
+import pytest
+from e2b_code_interpreter import Sandbox
+
+
+@pytest.mark.skip_debug()
+def test_env_vars_on_sandbox(template):
+ sandbox = Sandbox.create(template=template, envs={"TEST_ENV_VAR": "supertest"})
+ try:
+ result = sandbox.run_code('System.getProperty("TEST_ENV_VAR")', language="java")
+ assert result.text is not None
+ assert result.text.strip() == "supertest"
+ finally:
+ sandbox.kill()
+
+
+def test_env_vars_per_execution(sandbox: Sandbox):
+ try:
+ result = sandbox.run_code(
+ 'System.getProperty("FOO")', envs={"FOO": "bar"}, language="java"
+ )
+
+ result_empty = sandbox.run_code(
+ 'System.getProperty("FOO", "default")', language="java"
+ )
+
+ assert result.text is not None
+ assert result.text.strip() == "bar"
+ assert result_empty.text is not None
+ assert result_empty.text.strip() == "default"
+ finally:
+ sandbox.kill()
+
+
+@pytest.mark.skip_debug()
+def test_env_vars_overwrite(template):
+ sandbox = Sandbox.create(template=template, envs={"TEST_ENV_VAR": "supertest"})
+ try:
+ result = sandbox.run_code(
+ 'System.getProperty("TEST_ENV_VAR")',
+ language="java",
+ envs={"TEST_ENV_VAR": "overwrite"},
+ )
+ result_global_default = sandbox.run_code(
+ 'System.getProperty("TEST_ENV_VAR")', language="java"
+ )
+ assert result.text is not None
+ assert result.text.strip() == "overwrite"
+ assert result_global_default.text is not None
+ assert result_global_default.text.strip() == "supertest"
+ finally:
+ sandbox.kill()
diff --git a/python/tests/sync/env_vars/test_js.py b/python/tests/sync/env_vars/test_js.py
new file mode 100644
index 00000000..6561d65b
--- /dev/null
+++ b/python/tests/sync/env_vars/test_js.py
@@ -0,0 +1,51 @@
+import pytest
+from e2b_code_interpreter import Sandbox
+
+
+@pytest.mark.skip_debug()
+def test_env_vars_on_sandbox(template):
+ sandbox = Sandbox.create(template=template, envs={"TEST_ENV_VAR": "supertest"})
+ try:
+ result = sandbox.run_code("process.env.TEST_ENV_VAR", language="javascript")
+ assert result.text is not None
+ assert result.text.strip() == "supertest"
+ finally:
+ sandbox.kill()
+
+
+def test_env_vars_per_execution(sandbox: Sandbox):
+ try:
+ result = sandbox.run_code(
+ "process.env.FOO", envs={"FOO": "bar"}, language="javascript"
+ )
+
+ result_empty = sandbox.run_code(
+ "process.env.FOO || 'default'", language="javascript"
+ )
+
+ assert result.text is not None
+ assert result.text.strip() == "bar"
+ assert result_empty.text is not None
+ assert result_empty.text.strip() == "default"
+ finally:
+ sandbox.kill()
+
+
+@pytest.mark.skip_debug()
+def test_env_vars_overwrite(template):
+ sandbox = Sandbox.create(template=template, envs={"TEST_ENV_VAR": "supertest"})
+ try:
+ result = sandbox.run_code(
+ "process.env.TEST_ENV_VAR",
+ language="javascript",
+ envs={"TEST_ENV_VAR": "overwrite"},
+ )
+ result_global_default = sandbox.run_code(
+ "process.env.TEST_ENV_VAR", language="javascript"
+ )
+ assert result.text is not None
+ assert result.text.strip() == "overwrite"
+ assert result_global_default.text is not None
+ assert result_global_default.text.strip() == "supertest"
+ finally:
+ sandbox.kill()
diff --git a/python/tests/sync/env_vars/test_python.py b/python/tests/sync/env_vars/test_python.py
new file mode 100644
index 00000000..95170c75
--- /dev/null
+++ b/python/tests/sync/env_vars/test_python.py
@@ -0,0 +1,53 @@
+import pytest
+from e2b_code_interpreter import Sandbox
+
+
+@pytest.mark.skip_debug()
+def test_env_vars_on_sandbox(template):
+ sandbox = Sandbox.create(template=template, envs={"TEST_ENV_VAR": "supertest"})
+ try:
+ result = sandbox.run_code(
+ "import os; os.getenv('TEST_ENV_VAR')", language="python"
+ )
+ assert result.text is not None
+ assert result.text.strip() == "supertest"
+ finally:
+ sandbox.kill()
+
+
+def test_env_vars_per_execution(sandbox: Sandbox):
+ try:
+ result = sandbox.run_code(
+ "import os; os.getenv('FOO')", envs={"FOO": "bar"}, language="python"
+ )
+
+ result_empty = sandbox.run_code(
+ "import os; os.getenv('FOO', 'default')", language="python"
+ )
+
+ assert result.text is not None
+ assert result.text.strip() == "bar"
+ assert result_empty.text is not None
+ assert result_empty.text.strip() == "default"
+ finally:
+ sandbox.kill()
+
+
+@pytest.mark.skip_debug()
+def test_env_vars_overwrite(template):
+ sandbox = Sandbox.create(template=template, envs={"TEST_ENV_VAR": "supertest"})
+ try:
+ result = sandbox.run_code(
+ "import os; os.getenv('TEST_ENV_VAR')",
+ language="python",
+ envs={"TEST_ENV_VAR": "overwrite"},
+ )
+ result_global_default = sandbox.run_code(
+ "import os; os.getenv('TEST_ENV_VAR')", language="python"
+ )
+ assert result.text is not None
+ assert result.text.strip() == "overwrite"
+ assert result_global_default.text is not None
+ assert result_global_default.text.strip() == "supertest"
+ finally:
+ sandbox.kill()
diff --git a/python/tests/sync/env_vars/test_r.py b/python/tests/sync/env_vars/test_r.py
new file mode 100644
index 00000000..c1641116
--- /dev/null
+++ b/python/tests/sync/env_vars/test_r.py
@@ -0,0 +1,51 @@
+import pytest
+from e2b_code_interpreter import Sandbox
+
+
+@pytest.mark.skip_debug()
+def test_env_vars_on_sandbox(template):
+ sandbox = Sandbox.create(template=template, envs={"TEST_ENV_VAR": "supertest"})
+ try:
+ result = sandbox.run_code("Sys.getenv('TEST_ENV_VAR')", language="r")
+ assert result.results[0].text is not None
+ assert result.results[0].text.strip() == '[1] "supertest"'
+ finally:
+ sandbox.kill()
+
+
+def test_env_vars_per_execution(sandbox: Sandbox):
+ try:
+ result = sandbox.run_code(
+ "Sys.getenv('FOO')", envs={"FOO": "bar"}, language="r"
+ )
+
+ result_empty = sandbox.run_code(
+ "Sys.getenv('FOO', unset = 'default')", language="r"
+ )
+
+ assert result.results[0].text is not None
+ assert result.results[0].text.strip() == '[1] "bar"'
+ assert result_empty.results[0].text is not None
+ assert result_empty.results[0].text.strip() == '[1] "default"'
+ finally:
+ sandbox.kill()
+
+
+@pytest.mark.skip_debug()
+def test_env_vars_overwrite(template):
+ sandbox = Sandbox.create(template=template, envs={"TEST_ENV_VAR": "supertest"})
+ try:
+ result = sandbox.run_code(
+ "Sys.getenv('TEST_ENV_VAR')",
+ language="r",
+ envs={"TEST_ENV_VAR": "overwrite"},
+ )
+ result_global_default = sandbox.run_code(
+ "Sys.getenv('TEST_ENV_VAR')", language="r"
+ )
+ assert result.results[0].text is not None
+ assert result.results[0].text.strip() == '[1] "overwrite"'
+ assert result_global_default.results[0].text is not None
+ assert result_global_default.results[0].text.strip() == '[1] "supertest"'
+ finally:
+ sandbox.kill()
diff --git a/python/tests/sync/test_bash.py b/python/tests/sync/test_bash.py
new file mode 100644
index 00000000..7de9ccb6
--- /dev/null
+++ b/python/tests/sync/test_bash.py
@@ -0,0 +1,6 @@
+from e2b_code_interpreter.code_interpreter_sync import Sandbox
+
+
+def test_bash(sandbox: Sandbox):
+ result = sandbox.run_code("!pwd")
+ assert "".join(result.logs.stdout).strip() == "/home/user"
diff --git a/python/tests/sync/test_basic.py b/python/tests/sync/test_basic.py
new file mode 100644
index 00000000..30f94983
--- /dev/null
+++ b/python/tests/sync/test_basic.py
@@ -0,0 +1,16 @@
+import pytest
+
+from e2b_code_interpreter.code_interpreter_sync import Sandbox
+
+
+def test_basic(sandbox: Sandbox):
+ result = sandbox.run_code("x =1; x")
+ assert result.text == "1"
+
+
+@pytest.mark.skip_debug
+def test_secure_access(sandbox_factory):
+ sandbox = sandbox_factory(secure=True, network={"allow_public_traffic": False})
+ # Create sandbox with public traffic disabled (secure access)
+ result = sandbox.run_code("x =1; x")
+ assert result.text == "1"
diff --git a/python/tests/sync/test_callbacks.py b/python/tests/sync/test_callbacks.py
new file mode 100644
index 00000000..54c3359b
--- /dev/null
+++ b/python/tests/sync/test_callbacks.py
@@ -0,0 +1,36 @@
+from e2b_code_interpreter.code_interpreter_sync import Sandbox
+
+
+def test_resuls(sandbox: Sandbox):
+ results = []
+ execution = sandbox.run_code(
+ "x = 1;x", on_result=lambda result: results.append(result)
+ )
+ assert len(results) == 1
+ assert execution.results[0].text == "1"
+
+
+def test_error(sandbox: Sandbox):
+ errors = []
+ execution = sandbox.run_code("xyz", on_error=lambda error: errors.append(error))
+ assert len(errors) == 1
+ assert execution.error.name == "NameError"
+
+
+def test_stdout(sandbox: Sandbox):
+ stdout = []
+ execution = sandbox.run_code(
+ "print('Hello from e2b')", on_stdout=lambda out: stdout.append(out)
+ )
+ assert len(stdout) == 1
+ assert execution.logs.stdout == ["Hello from e2b\n"]
+
+
+def test_stderr(sandbox: Sandbox):
+ stderr = []
+ execution = sandbox.run_code(
+ 'import sys;print("This is an error message", file=sys.stderr)',
+ on_stderr=lambda err: stderr.append(err),
+ )
+ assert len(stderr) == 1
+ assert execution.logs.stderr == ["This is an error message\n"]
diff --git a/python/tests/sync/test_contexts.py b/python/tests/sync/test_contexts.py
new file mode 100644
index 00000000..0b8278f5
--- /dev/null
+++ b/python/tests/sync/test_contexts.py
@@ -0,0 +1,120 @@
+import pytest
+
+from e2b_code_interpreter.code_interpreter_sync import Sandbox
+
+
+def test_create_context_with_no_options(sandbox: Sandbox):
+ context = sandbox.create_code_context()
+
+ contexts = sandbox.list_code_contexts()
+ last_context = contexts[-1]
+
+ assert last_context.id == context.id
+ assert last_context.language == context.language
+ assert last_context.cwd == context.cwd
+
+
+def test_create_context_with_options(sandbox: Sandbox):
+ context = sandbox.create_code_context(
+ language="python",
+ cwd="/root",
+ )
+
+ contexts = sandbox.list_code_contexts()
+ last_context = contexts[-1]
+
+ assert last_context.id == context.id
+ assert last_context.language == context.language
+ assert last_context.cwd == context.cwd
+
+
+def test_remove_context(sandbox: Sandbox):
+ context = sandbox.create_code_context()
+
+ sandbox.remove_code_context(context.id)
+
+ contexts = sandbox.list_code_contexts()
+ assert context.id not in [ctx.id for ctx in contexts]
+
+
+def test_list_contexts(sandbox: Sandbox):
+ contexts = sandbox.list_code_contexts()
+
+ # default contexts should include python and javascript
+ languages = [context.language for context in contexts]
+ assert "python" in languages
+ assert "javascript" in languages
+
+
+def test_restart_context(sandbox: Sandbox):
+ context = sandbox.create_code_context()
+
+ # set a variable in the context
+ sandbox.run_code("x = 1", context=context)
+
+ # restart the context
+ sandbox.restart_code_context(context.id)
+
+ # check that the variable no longer exists
+ execution = sandbox.run_code("x", context=context)
+
+ # check for a NameError with message "name 'x' is not defined"
+ assert execution.error is not None
+ assert execution.error.name == "NameError"
+ assert execution.error.value == "name 'x' is not defined"
+
+
+# Secure traffic tests (public traffic disabled)
+@pytest.mark.skip_debug
+def test_create_context_secure_traffic(sandbox_factory):
+ sandbox = sandbox_factory(secure=True, network={"allow_public_traffic": False})
+ context = sandbox.create_code_context()
+
+ contexts = sandbox.list_code_contexts()
+ last_context = contexts[-1]
+
+ assert last_context.id == context.id
+ assert last_context.language == context.language
+ assert last_context.cwd == context.cwd
+
+
+@pytest.mark.skip_debug
+def test_remove_context_secure_traffic(sandbox_factory):
+ sandbox = sandbox_factory(secure=True, network={"allow_public_traffic": False})
+ context = sandbox.create_code_context()
+
+ sandbox.remove_code_context(context.id)
+
+ contexts = sandbox.list_code_contexts()
+ assert context.id not in [ctx.id for ctx in contexts]
+
+
+@pytest.mark.skip_debug
+def test_list_contexts_secure_traffic(sandbox_factory):
+ sandbox = sandbox_factory(secure=True, network={"allow_public_traffic": False})
+ contexts = sandbox.list_code_contexts()
+
+ # default contexts should include python and javascript
+ languages = [context.language for context in contexts]
+ assert "python" in languages
+ assert "javascript" in languages
+
+
+@pytest.mark.skip_debug
+def test_restart_context_secure_traffic(sandbox_factory):
+ sandbox = sandbox_factory(secure=True, network={"allow_public_traffic": False})
+ context = sandbox.create_code_context()
+
+ # set a variable in the context
+ sandbox.run_code("x = 1", context=context)
+
+ # restart the context
+ sandbox.restart_code_context(context.id)
+
+ # check that the variable no longer exists
+ execution = sandbox.run_code("x", context=context)
+
+ # check for a NameError with message "name 'x' is not defined"
+ assert execution.error is not None
+ assert execution.error.name == "NameError"
+ assert execution.error.value == "name 'x' is not defined"
diff --git a/python/tests/sync/test_custom_repr_object.py b/python/tests/sync/test_custom_repr_object.py
new file mode 100644
index 00000000..8423c950
--- /dev/null
+++ b/python/tests/sync/test_custom_repr_object.py
@@ -0,0 +1,12 @@
+from e2b_code_interpreter.code_interpreter_sync import Sandbox
+
+code = """
+from IPython.display import display
+
+display({'text/latex': r'\text{CustomReprObject}'}, raw=True)
+"""
+
+
+def test_bash(sandbox: Sandbox):
+ execution = sandbox.run_code(code)
+ assert execution.results[0].formats() == ["latex"]
diff --git a/python/tests/sync/test_cwd.py b/python/tests/sync/test_cwd.py
new file mode 100644
index 00000000..b238f7e9
--- /dev/null
+++ b/python/tests/sync/test_cwd.py
@@ -0,0 +1,39 @@
+import pytest
+
+from e2b_code_interpreter.code_interpreter_sync import Sandbox
+
+
+@pytest.mark.skip_debug()
+def test_cwd_python(sandbox: Sandbox):
+ result = sandbox.run_code("from pathlib import Path; print(Path.cwd())")
+ assert "".join(result.logs.stdout).strip() == "/home/user"
+
+
+@pytest.mark.skip_debug()
+def test_cwd_javascript(sandbox: Sandbox):
+ result = sandbox.run_code("process.cwd()", language="js")
+ assert result.text == "/home/user"
+
+
+@pytest.mark.skip_debug()
+def test_cwd_typescript(sandbox: Sandbox):
+ result = sandbox.run_code("process.cwd()", language="ts")
+ assert result.text == "/home/user"
+
+
+@pytest.mark.skip_debug()
+def test_cwd_r(sandbox: Sandbox):
+ result = sandbox.run_code("getwd()", language="r")
+ assert result.results[0].text.strip() == '[1] "/home/user"'
+
+
+@pytest.mark.skip_debug()
+def test_cwd_java(sandbox: Sandbox):
+ result = sandbox.run_code('System.getProperty("user.dir")', language="java")
+ assert result.results[0].text.strip() == "/home/user"
+
+
+@pytest.mark.skip_debug()
+def test_cwd_bash(sandbox: Sandbox):
+ result = sandbox.run_code("pwd", language="bash")
+ assert "".join(result.logs.stdout).strip() == "/home/user"
diff --git a/python/tests/sync/test_data.py b/python/tests/sync/test_data.py
new file mode 100644
index 00000000..4db51d65
--- /dev/null
+++ b/python/tests/sync/test_data.py
@@ -0,0 +1,17 @@
+from e2b_code_interpreter.code_interpreter_sync import Sandbox
+
+
+def test_data(sandbox: Sandbox):
+ # plot random chart
+ result = sandbox.run_code(
+ """
+ import pandas as pd
+ pd.DataFrame({"a": [1, 2, 3]})
+ """
+ )
+
+ # there's your image
+ data = result.results[0]
+ assert data.data
+ assert "a" in data.data
+ assert len(data.data["a"]) == 3
diff --git a/python/tests/sync/test_default_kernels.py b/python/tests/sync/test_default_kernels.py
new file mode 100644
index 00000000..8dfd4bf9
--- /dev/null
+++ b/python/tests/sync/test_default_kernels.py
@@ -0,0 +1,49 @@
+import pytest
+
+from e2b_code_interpreter.code_interpreter_sync import Sandbox
+
+
+def test_js_kernel(sandbox: Sandbox):
+ execution = sandbox.run_code("console.log('Hello, World!')", language="js")
+ assert execution.logs.stdout == ["Hello, World!\n"]
+
+
+@pytest.mark.skip_debug()
+def test_r_kernel(sandbox: Sandbox):
+ execution = sandbox.run_code('print("Hello, World!")', language="r")
+ assert execution.logs.stdout == ['[1] "Hello, World!"\n']
+
+
+@pytest.mark.skip_debug()
+def test_java_kernel(sandbox: Sandbox):
+ execution = sandbox.run_code('System.out.println("Hello, World!")', language="java")
+ assert execution.logs.stdout[0] == "Hello, World!"
+
+
+def test_js_esm_imports(sandbox: Sandbox):
+ execution = sandbox.run_code(
+ """
+ import { readFileSync } from 'fs'
+ console.log(typeof readFileSync)
+ """,
+ language="js",
+ )
+ assert execution.logs.stdout == ["function\n"]
+
+
+def test_js_top_level_await(sandbox: Sandbox):
+ execution = sandbox.run_code(
+ """
+ await Promise.resolve('Hello World!')
+ """,
+ language="js",
+ )
+ assert execution.text == "Hello World!"
+
+
+@pytest.mark.skip_debug()
+def test_ts_kernel(sandbox: Sandbox):
+ execution = sandbox.run_code(
+ "const message: string = 'Hello, World!'; console.log(message)", language="ts"
+ )
+ assert execution.logs.stdout == ["Hello, World!\n"]
diff --git a/python/tests/sync/test_display_data.py b/python/tests/sync/test_display_data.py
new file mode 100644
index 00000000..1cb44b97
--- /dev/null
+++ b/python/tests/sync/test_display_data.py
@@ -0,0 +1,23 @@
+from e2b_code_interpreter.code_interpreter_sync import Sandbox
+
+
+def test_display_data(sandbox: Sandbox):
+ # plot random chart
+ result = sandbox.run_code(
+ """
+ import matplotlib.pyplot as plt
+ import numpy as np
+
+ x = np.linspace(0, 20, 100)
+ y = np.sin(x)
+
+ plt.plot(x, y)
+ plt.show()
+ """
+ )
+
+ # there's your image
+ data = result.results[0]
+ assert data.png
+ assert data.text
+ assert not data.extra
diff --git a/python/tests/sync/test_execution_count.py b/python/tests/sync/test_execution_count.py
new file mode 100644
index 00000000..98e2039f
--- /dev/null
+++ b/python/tests/sync/test_execution_count.py
@@ -0,0 +1,10 @@
+import pytest
+
+from e2b_code_interpreter.code_interpreter_sync import Sandbox
+
+
+@pytest.mark.skip_debug()
+def test_execution_count(sandbox: Sandbox):
+ sandbox.run_code("echo 'E2B is awesome!'")
+ result = sandbox.run_code("!pwd")
+ assert result.execution_count == 2
diff --git a/python/tests/sync/test_interrupt.py b/python/tests/sync/test_interrupt.py
new file mode 100644
index 00000000..d4c5ff15
--- /dev/null
+++ b/python/tests/sync/test_interrupt.py
@@ -0,0 +1,23 @@
+import time
+
+import pytest
+
+from e2b import TimeoutException
+from e2b_code_interpreter.code_interpreter_sync import Sandbox
+
+
+def test_subsequent_execution_works_after_client_timeout(sandbox: Sandbox):
+ # Start a long-running execution with a short timeout.
+ # This simulates a client disconnect: the SDK closes the connection,
+ # which should trigger the server to interrupt the kernel (#213).
+ with pytest.raises(TimeoutException):
+ sandbox.run_code("import time; time.sleep(300)", timeout=3)
+
+ # Wait for the server to detect the disconnect (via keepalive write
+ # failure) and interrupt the kernel.
+ time.sleep(5)
+
+ # Run a simple execution. Without the kernel interrupt fix, this would
+ # block behind the still-running sleep(30) and time out.
+ result = sandbox.run_code("1 + 1", timeout=10)
+ assert result.text == "2"
diff --git a/python/tests/sync/test_kernels.py b/python/tests/sync/test_kernels.py
new file mode 100644
index 00000000..17d6430f
--- /dev/null
+++ b/python/tests/sync/test_kernels.py
@@ -0,0 +1,23 @@
+import pytest
+from e2b import InvalidArgumentException
+
+from e2b_code_interpreter.code_interpreter_sync import Sandbox
+
+
+def test_create_new_kernel(sandbox: Sandbox):
+ sandbox.create_code_context()
+
+
+def test_independence_of_kernels(sandbox: Sandbox):
+ context = sandbox.create_code_context()
+ sandbox.run_code("x = 1")
+
+ r = sandbox.run_code("x", context=context)
+ assert r.error is not None
+ assert r.error.value == "name 'x' is not defined"
+
+
+def test_pass_context_and_language(sandbox: Sandbox):
+ context = sandbox.create_code_context(language="python")
+ with pytest.raises(InvalidArgumentException):
+ sandbox.run_code("console.log('Hello, World!')", language="js", context=context)
diff --git a/python/tests/sync/test_reconnect.py b/python/tests/sync/test_reconnect.py
new file mode 100644
index 00000000..f74b73de
--- /dev/null
+++ b/python/tests/sync/test_reconnect.py
@@ -0,0 +1,12 @@
+import pytest
+
+from e2b_code_interpreter.code_interpreter_sync import Sandbox
+
+
+@pytest.mark.skip_debug
+def test_reconnect(sandbox: Sandbox):
+ sandbox_id = sandbox.sandbox_id
+
+ sandbox2 = Sandbox.connect(sandbox_id)
+ result = sandbox2.run_code("x =1; x")
+ assert result.text == "1"
diff --git a/python/tests/sync/test_statefulness.py b/python/tests/sync/test_statefulness.py
new file mode 100644
index 00000000..044478db
--- /dev/null
+++ b/python/tests/sync/test_statefulness.py
@@ -0,0 +1,8 @@
+from e2b_code_interpreter.code_interpreter_sync import Sandbox
+
+
+def test_stateful(sandbox: Sandbox):
+ sandbox.run_code("test_stateful = 1")
+
+ result = sandbox.run_code("test_stateful+=1; test_stateful")
+ assert result.text == "2"
diff --git a/python/tests/sync/test_streaming.py b/python/tests/sync/test_streaming.py
new file mode 100644
index 00000000..fa7a3c4a
--- /dev/null
+++ b/python/tests/sync/test_streaming.py
@@ -0,0 +1,43 @@
+from e2b_code_interpreter.code_interpreter_sync import Sandbox
+
+
+def test_streaming_output(sandbox: Sandbox):
+ out = []
+
+ def test(line) -> None:
+ out.append(line)
+ return
+
+ sandbox.run_code("print(1)", on_stdout=test)
+
+ assert len(out) == 1
+ assert out[0].line == "1\n"
+
+
+def test_streaming_error(sandbox: Sandbox):
+ out = []
+
+ sandbox.run_code("import sys;print(1, file=sys.stderr)", on_stderr=out.append)
+
+ assert len(out) == 1
+ assert out[0].line == "1\n"
+
+
+def test_streaming_result(sandbox: Sandbox):
+ code = """
+ import matplotlib.pyplot as plt
+ import numpy as np
+
+ x = np.linspace(0, 20, 100)
+ y = np.sin(x)
+
+ plt.plot(x, y)
+ plt.show()
+
+ x
+ """
+
+ out = []
+ sandbox.run_code(code, on_result=out.append)
+
+ assert len(out) == 2
diff --git a/python/tests/sync/test_systemd.py b/python/tests/sync/test_systemd.py
new file mode 100644
index 00000000..574ed7d0
--- /dev/null
+++ b/python/tests/sync/test_systemd.py
@@ -0,0 +1,59 @@
+import time
+
+import pytest
+
+from e2b_code_interpreter.code_interpreter_sync import Sandbox
+
+
+def wait_for_health(sandbox: Sandbox, max_retries=10, interval_ms=100):
+ for _ in range(max_retries):
+ try:
+ result = sandbox.commands.run(
+ 'curl -s -o /dev/null -w "%{http_code}" http://0.0.0.0:49999/health'
+ )
+ if result.stdout.strip() == "200":
+ return True
+ except Exception:
+ pass
+ time.sleep(interval_ms / 1000)
+ return False
+
+
+@pytest.mark.skip_debug
+def test_restart_after_jupyter_kill(sandbox: Sandbox):
+ # Verify health is up initially
+ assert wait_for_health(sandbox)
+
+ # Kill the jupyter process as root
+ # The command handle may get killed too (killing jupyter cascades to code-interpreter),
+ # so we catch the error.
+ try:
+ sandbox.commands.run("kill -9 $(pgrep -f 'jupyter server')", user="root")
+ except Exception:
+ pass
+
+ # Wait for systemd to restart both services
+ assert wait_for_health(sandbox, 60, 500)
+
+ # Verify code execution works after recovery
+ result = sandbox.run_code("x = 1; x")
+ assert result.text == "1"
+
+
+@pytest.mark.skip_debug
+def test_restart_after_code_interpreter_kill(sandbox: Sandbox):
+ # Verify health is up initially
+ assert wait_for_health(sandbox)
+
+ # Kill the code-interpreter process as root
+ try:
+ sandbox.commands.run("kill -9 $(pgrep -f 'uvicorn main:app')", user="root")
+ except Exception:
+ pass
+
+ # Wait for systemd to restart it and health to come back
+ assert wait_for_health(sandbox, 60, 500)
+
+ # Verify code execution works after recovery
+ result = sandbox.run_code("x = 1; x")
+ assert result.text == "1"
diff --git a/python/tests/test_bash.py b/python/tests/test_bash.py
deleted file mode 100644
index 3ffe6393..00000000
--- a/python/tests/test_bash.py
+++ /dev/null
@@ -1,7 +0,0 @@
-from e2b_code_interpreter.main import CodeInterpreter
-
-
-def test_bash():
- with CodeInterpreter() as sandbox:
- result = sandbox.notebook.exec_cell("!pwd")
- assert "".join(result.logs.stdout).strip() == "/home/user"
diff --git a/python/tests/test_basic.py b/python/tests/test_basic.py
deleted file mode 100644
index 87f64518..00000000
--- a/python/tests/test_basic.py
+++ /dev/null
@@ -1,7 +0,0 @@
-from e2b_code_interpreter.main import CodeInterpreter
-
-
-def test_basic():
- with CodeInterpreter() as sandbox:
- result = sandbox.notebook.exec_cell("x =1; x")
- assert result.text == "1"
diff --git a/python/tests/test_display_data.py b/python/tests/test_display_data.py
deleted file mode 100644
index 703860be..00000000
--- a/python/tests/test_display_data.py
+++ /dev/null
@@ -1,23 +0,0 @@
-from e2b_code_interpreter.main import CodeInterpreter
-
-
-def test_display_data():
- with CodeInterpreter() as sandbox:
- # plot random graph
- result = sandbox.notebook.exec_cell(
- """
- import matplotlib.pyplot as plt
- import numpy as np
-
- x = np.linspace(0, 20, 100)
- y = np.sin(x)
-
- plt.plot(x, y)
- plt.show()
- """
- )
-
- # there's your image
- data = result.results[0]
- assert data.png
- assert data.text
diff --git a/python/tests/test_kernels.py b/python/tests/test_kernels.py
deleted file mode 100644
index 73d00671..00000000
--- a/python/tests/test_kernels.py
+++ /dev/null
@@ -1,48 +0,0 @@
-from e2b_code_interpreter.main import CodeInterpreter
-
-
-def test_create_new_kernel():
- with CodeInterpreter() as sandbox:
- sandbox.notebook.create_kernel()
-
-
-def test_independence_of_kernels():
- with CodeInterpreter() as sandbox:
- kernel_id = sandbox.notebook.create_kernel()
- sandbox.notebook.exec_cell("x = 1")
-
- r = sandbox.notebook.exec_cell("x", kernel_id=kernel_id)
- assert r.error.value == "name 'x' is not defined"
-
-
-def test_restart_kernel():
- with CodeInterpreter() as sandbox:
- sandbox.notebook.exec_cell("x = 1")
- sandbox.notebook.restart_kernel()
-
- r = sandbox.notebook.exec_cell("x")
- assert r.error.value == "name 'x' is not defined"
-
-
-def test_list_kernels():
- with CodeInterpreter() as sandbox:
- kernels = sandbox.notebook.list_kernels()
- assert len(kernels) == 1
-
- kernel_id = sandbox.notebook.create_kernel()
- kernels = sandbox.notebook.list_kernels()
- assert kernel_id in kernels
- assert len(kernels) == 2
-
-
-def test_shutdown():
- with CodeInterpreter() as sandbox:
- kernel_id = sandbox.notebook.create_kernel()
- kernels = sandbox.notebook.list_kernels()
- assert kernel_id in kernels
- assert len(kernels) == 2
-
- sandbox.notebook.shutdown_kernel(kernel_id)
- kernels = sandbox.notebook.list_kernels()
- assert kernel_id not in kernels
- assert len(kernels) == 1
diff --git a/python/tests/test_reconnect.py b/python/tests/test_reconnect.py
deleted file mode 100644
index 5a3669c4..00000000
--- a/python/tests/test_reconnect.py
+++ /dev/null
@@ -1,12 +0,0 @@
-from e2b_code_interpreter.main import CodeInterpreter
-
-
-def test_reconnect():
- with CodeInterpreter() as sandbox:
- sandbox_id = sandbox.id
-
- sandbox = CodeInterpreter.reconnect(sandbox_id)
- result = sandbox.notebook.exec_cell("x =1; x")
- assert result.text == "1"
-
- sandbox.close()
diff --git a/python/tests/test_statefulness.py b/python/tests/test_statefulness.py
deleted file mode 100644
index fdc0c8ea..00000000
--- a/python/tests/test_statefulness.py
+++ /dev/null
@@ -1,9 +0,0 @@
-from e2b_code_interpreter.main import CodeInterpreter
-
-
-def test_stateful():
- with CodeInterpreter() as sandbox:
- sandbox.notebook.exec_cell("x = 1")
-
- result = sandbox.notebook.exec_cell("x+=1; x")
- assert result.text == "2"
diff --git a/python/tests/test_streaming.py b/python/tests/test_streaming.py
deleted file mode 100644
index 4e1e00cc..00000000
--- a/python/tests/test_streaming.py
+++ /dev/null
@@ -1,47 +0,0 @@
-from e2b_code_interpreter.main import CodeInterpreter
-
-
-def test_streaming_output():
- out = []
- with CodeInterpreter() as sandbox:
-
- def test(line) -> int:
- out.append(line)
- return 1
-
- sandbox.notebook.exec_cell("print(1)", on_stdout=test)
-
- assert len(out) == 1
- assert out[0].line == "1\n"
-
-
-def test_streaming_error():
- out = []
- with CodeInterpreter() as sandbox:
- sandbox.notebook.exec_cell(
- "import sys;print(1, file=sys.stderr)", on_stderr=out.append
- )
-
- assert len(out) == 1
- assert out[0].line == "1\n"
-
-
-def test_streaming_result():
- code = """
- import matplotlib.pyplot as plt
- import numpy as np
-
- x = np.linspace(0, 20, 100)
- y = np.sin(x)
-
- plt.plot(x, y)
- plt.show()
-
- x
- """
-
- out = []
- with CodeInterpreter() as sandbox:
- sandbox.notebook.exec_cell(code, on_result=out.append)
-
- assert len(out) == 2
diff --git a/readme-assets/e2b-code-interpreter-dark.png b/readme-assets/e2b-code-interpreter-dark.png
new file mode 100644
index 00000000..723ca497
Binary files /dev/null and b/readme-assets/e2b-code-interpreter-dark.png differ
diff --git a/readme-assets/e2b-code-interpreter-light.png b/readme-assets/e2b-code-interpreter-light.png
new file mode 100644
index 00000000..5b58fae8
Binary files /dev/null and b/readme-assets/e2b-code-interpreter-light.png differ
diff --git a/readme-assets/logo-circle.png b/readme-assets/logo-circle.png
new file mode 100644
index 00000000..445b20c7
Binary files /dev/null and b/readme-assets/logo-circle.png differ
diff --git a/renovate.json5 b/renovate.json5
new file mode 100644
index 00000000..616f7b69
--- /dev/null
+++ b/renovate.json5
@@ -0,0 +1,36 @@
+// configuration options: https://docs.renovatebot.com/configuration-options/
+// list of all presets: https://docs.renovatebot.com/presets-default/
+{
+ $schema: 'https://docs.renovatebot.com/renovate-schema.json',
+ extends: ['config:recommended', ':automergeRequireAllStatusChecks'],
+ dependencyDashboard: true,
+ // let it fly for now, we've got a lot to catch up on
+ // schedule: [
+ // "0 * * * *"
+ // ],
+ timezone: 'UTC',
+ // Always squash PRs when automerging
+ automergeType: 'pr',
+ automergeStrategy: 'squash',
+ packageRules: [
+ {
+ description: 'Group and automerge patch updates after CI passes',
+ matchUpdateTypes: ['patch'],
+ automerge: true,
+ groupName: 'patch-updates',
+ },
+ {
+ description: 'Create PRs for minor updates without automerge',
+ matchUpdateTypes: ['minor'],
+ automerge: false,
+ },
+ {
+ description: 'Require dashboard approval for major updates',
+ matchUpdateTypes: ['major'],
+ dependencyDashboardApproval: true,
+ automerge: false,
+ },
+ ],
+ prConcurrentLimit: 3,
+ rebaseWhen: 'auto',
+}
diff --git a/template/README.md b/template/README.md
index 168c3131..4f64fabe 100644
--- a/template/README.md
+++ b/template/README.md
@@ -1,43 +1,124 @@
-# Using custom sandbox with Code Interpreter SDK
+# Code Interpreter
-If you want to customize the Code Interprerter sandbox (e.g.: add a preinstalled package) you can do that by using a [custom sandbox template](https://e2b.dev/docs/sandbox/templates/overview).
+## Building the production template
+To build the official `code-interpreter-v1` template from this repo, use
+`build_prod.py`. This is the script CI and releases run.
-## Step-by-step guide
-1. Create custom sandbox by following [this guide](https://e2b.dev/docs/guide/custom-sandbox)
+1. Install the build dependencies:
-2. Use prebuilt [E2B Code Interpreter image](https://hub.docker.com/r/e2bdev/code-interpreter) by replacing the `FROM` command in your `e2b.Dockerfile` with following
+```
+pip install -r requirements-dev.txt
+```
- ```Dockerfile
- FROM e2bdev/code-interpreter:latest
- ```
+2. Provide your credentials in `.env`:
-3. Copy [`start-up.sh`](./start-up.sh) to the same directory where's your `e2b.toml`
+```
+E2B_API_KEY=e2b_***
+```
-4. Run the following in the same directory where's your `e2b.toml`
- ```sh
- e2b template build -c "/home/user/.jupyter/start-up.sh"
- ```
+3. Build the template:
-5. Use your custom sandbox with Code Interpreter SDK
+```
+python build_prod.py
+```
- **Python**
- ```python
- from e2b_code_interpreter import CodeInterpreter
- sandbox = CodeInterpreter(template="your-custom-sandbox-name")
- execution = sandbox.notebook.exec_cell("print('hello')")
- sandbox.close()
+Set `SKIP_CACHE=true` to force a clean rebuild that ignores the layer cache:
- # Or you can use `with` which handles closing the sandbox for you
- with CodeInterpreter(template="your-custom-sandbox-name") as sandbox:
- execution = sandbox.notebook.exec_cell("print('hello')")
- ```
-
+```
+SKIP_CACHE=true python build_prod.py
+```
- **JavaScript/TypeScript**
- ```js
- import { CodeInterpreter } from '@e2b/code-interpreter'
- const sandbox = await CodeInterpreter.create({ template: 'your-custom-sandbox-name' })
- const execution = await sandbox.notebook.execCell('print("hello")')
- await sandbox.close()
- ```
+If you want to customize the Code Interpreter sandbox (e.g.: add a preinstalled package) you can do that by creating a [custom sandbox template](https://e2b.dev/docs/template/quickstart).
+
+## Creating a custom template
+
+1. Install E2B SDK
+
+```
+pip install e2b dotenv
+```
+
+2. Create a custom sandbox template:
+
+**template.py**
+
+```python
+from e2b import Template
+
+template = Template().from_template("code-interpreter-v1")
+```
+
+3. Create a build script:
+
+**build.py**
+
+```python
+from dotenv import load_dotenv
+from .template import template
+from e2b import Template, default_build_logger
+
+load_dotenv()
+
+Template.build(
+ template,
+ alias="code-interpreter-custom",
+ cpu_count=2,
+ memory_mb=2048,
+ on_build_logs=default_build_logger(),
+)
+```
+
+4. Set your environment variables in a `.env` file (loaded by `load_dotenv()`):
+
+```
+E2B_API_KEY=e2b_***
+```
+
+5. Build the template:
+
+```
+python build.py
+```
+
+6. Use the custom template:
+
+```python
+from e2b import Sandbox
+
+sbx = Sandbox.create(template="code-interpreter-custom")
+execution = sbx.run_code("print('Hello, World!')")
+print(execution.logs.stdout)
+```
+
+## Debugging a server that won't start
+
+The template runs Jupyter and the code-interpreter server as **systemd**
+services (`systemd/jupyter.service`, `systemd/code-interpreter.service`). This is
+the path CI and production use — note it is *different* from `make
+start-template-server`, which runs the Docker `start-up.sh` path. The two can
+diverge, so a server that boots fine under Docker may still fail under systemd.
+
+When a build fails its readiness check (`Waiting for template to be ready ...
+timed out`), the real cause is in the service journals. To see them:
+
+```
+make debug-template
+```
+
+This builds a debug template (gated on a fixed timeout instead of `/health`, so
+it finalizes even while the server is crash-looping), spawns a sandbox, and
+prints `systemctl status` + the full `journalctl` for both services. It needs
+`template/.env` with your `E2B_API_KEY` and the deps from `requirements-dev.txt`.
+
+The debug build also applies a systemd drop-in that routes Jupyter's stdout to
+the journal (`make_template(debug=True)`). Production builds keep
+`StandardOutput=null`, so Jupyter's request/error logs are only captured in the
+debug template.
+
+Inside a running sandbox you can also inspect things directly:
+
+```
+journalctl -u jupyter -u code-interpreter
+systemctl status code-interpreter
+```
diff --git a/template/build_ci.py b/template/build_ci.py
new file mode 100644
index 00000000..13c0c311
--- /dev/null
+++ b/template/build_ci.py
@@ -0,0 +1,19 @@
+import os
+from e2b import Template, default_build_logger
+from template import make_template
+
+build_info = Template.build(
+ make_template(),
+ alias=os.environ["E2B_TESTS_TEMPLATE"],
+ cpu_count=2,
+ memory_mb=2048,
+ on_build_logs=default_build_logger(),
+)
+
+template_id = build_info.template_id
+print(f"Built template ID: {template_id}")
+
+github_output = os.getenv("GITHUB_OUTPUT")
+if github_output:
+ with open(github_output, "a", encoding="utf-8") as fh:
+ fh.write(f"template_id={template_id}\n")
diff --git a/template/build_debug.py b/template/build_debug.py
new file mode 100644
index 00000000..f4dc63b4
--- /dev/null
+++ b/template/build_debug.py
@@ -0,0 +1,23 @@
+import os
+
+from dotenv import load_dotenv
+from e2b import Template, default_build_logger, wait_for_timeout
+from template import make_template
+
+load_dotenv()
+
+alias = os.getenv("E2B_DEBUG_TEMPLATE", "code-interpreter-debug")
+
+Template.build(
+ make_template(
+ kernels=["python", "javascript"],
+ ready=wait_for_timeout(60_000),
+ debug=True,
+ ),
+ alias=alias,
+ cpu_count=2,
+ memory_mb=2048,
+ on_build_logs=default_build_logger(min_level="debug"),
+)
+
+print(f"Built debug template: {alias}")
diff --git a/template/build_docker.py b/template/build_docker.py
new file mode 100644
index 00000000..7d1438a8
--- /dev/null
+++ b/template/build_docker.py
@@ -0,0 +1,5 @@
+from template import make_template
+from e2b import Template
+
+tmp = make_template(kernels=["python", "javascript"], is_docker=True)
+print(Template.to_dockerfile(tmp))
diff --git a/template/build_prod.py b/template/build_prod.py
new file mode 100644
index 00000000..1615ebff
--- /dev/null
+++ b/template/build_prod.py
@@ -0,0 +1,18 @@
+import os
+
+from dotenv import load_dotenv
+from e2b import Template, default_build_logger
+from template import make_template
+
+load_dotenv()
+
+skip_cache = os.getenv("SKIP_CACHE", "false").lower() == "true"
+
+Template.build(
+ make_template(),
+ alias="code-interpreter-v1",
+ cpu_count=2,
+ memory_mb=2048,
+ skip_cache=skip_cache,
+ on_build_logs=default_build_logger(),
+)
diff --git a/template/build_test.py b/template/build_test.py
new file mode 100644
index 00000000..a11128ca
--- /dev/null
+++ b/template/build_test.py
@@ -0,0 +1,13 @@
+from dotenv import load_dotenv
+from e2b import Template, default_build_logger
+from template import make_template
+
+load_dotenv()
+
+Template.build(
+ make_template(kernels=["python", "javascript"]),
+ alias="code-interpreter-dev",
+ cpu_count=2,
+ memory_mb=2048,
+ on_build_logs=default_build_logger(min_level="debug"),
+)
diff --git a/template/debug_logs.py b/template/debug_logs.py
new file mode 100644
index 00000000..cdd7b49a
--- /dev/null
+++ b/template/debug_logs.py
@@ -0,0 +1,35 @@
+import os
+
+from dotenv import load_dotenv
+from e2b import Sandbox
+
+load_dotenv()
+
+alias = os.getenv("E2B_DEBUG_TEMPLATE", "code-interpreter-debug")
+
+sbx = Sandbox.create(template=alias, timeout=600)
+print(f"sandbox: {sbx.sandbox_id}")
+
+CMDS = [
+ "systemctl --no-pager status jupyter || true",
+ "systemctl --no-pager status code-interpreter || true",
+ "journalctl --no-pager -u jupyter || true",
+ "journalctl --no-pager -u code-interpreter || true",
+ "curl -s --max-time 3 -o /dev/null -w 'jupyter :8888 -> %{http_code}\\n' http://localhost:8888/api/status || true",
+ "curl -s --max-time 3 -o /dev/null -w 'server :49999 -> %{http_code}\\n' http://localhost:49999/health || true",
+]
+
+try:
+ for cmd in CMDS:
+ print(f"\n===== $ {cmd} =====")
+ try:
+ result = sbx.commands.run(f"sudo bash -lc {cmd!r}", timeout=60)
+ if result.stdout:
+ print(result.stdout)
+ if result.stderr:
+ print("[stderr]", result.stderr)
+ except Exception as e:
+ # Keep going so one slow/failed command doesn't skip the rest.
+ print(f"[command failed] {e}")
+finally:
+ sbx.kill()
diff --git a/template/e2b.Dockerfile b/template/e2b.Dockerfile
deleted file mode 100644
index 071592ad..00000000
--- a/template/e2b.Dockerfile
+++ /dev/null
@@ -1,20 +0,0 @@
-FROM python:3.10
-
-RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y --no-install-recommends \
- build-essential curl git util-linux jq
-
-ENV PIP_DEFAULT_TIMEOUT=100 \
- PIP_DISABLE_PIP_VERSION_CHECK=1 \
- PIP_NO_CACHE_DIR=1 \
- JUPYTER_CONFIG_PATH="/home/user/.jupyter"
-
-
-COPY ./requirements.txt requirements.txt
-RUN pip install --no-cache-dir -r requirements.txt && ipython kernel install --name "python3" --user
-COPY ./jupyter_server_config.py /home/user/.jupyter/
-
-RUN mkdir -p /home/user/.ipython/profile_default
-COPY ipython_kernel_config.py /home/user/.ipython/profile_default/
-
-COPY ./start-up.sh /home/user/.jupyter/
-RUN chmod +x /home/user/.jupyter/start-up.sh
\ No newline at end of file
diff --git a/template/e2b.toml b/template/e2b.toml
deleted file mode 100644
index f2a59693..00000000
--- a/template/e2b.toml
+++ /dev/null
@@ -1,16 +0,0 @@
-# This is a config for E2B sandbox template.
-# You can use 'template_id' (1tsfj5yvigmgc5gmgqz2) or 'template_name (code-interpreter-stateful) from this config to spawn a sandbox:
-
-# Python SDK
-# from e2b import Sandbox
-# sandbox = Sandbox(template='code-interpreter-stateful')
-
-# JS SDK
-# import { Sandbox } from 'e2b'
-# const sandbox = await Sandbox.create({ template: 'code-interpreter-stateful' })
-
-memory_mb = 1_024
-start_cmd = "/home/user/.jupyter/start-up.sh"
-dockerfile = "e2b.Dockerfile"
-template_name = "code-interpreter-stateful"
-template_id = "1tsfj5yvigmgc5gmgqz2"
diff --git a/template/ipython_kernel_config.py b/template/ipython_kernel_config.py
index 58c8ec2d..26900faa 100644
--- a/template/ipython_kernel_config.py
+++ b/template/ipython_kernel_config.py
@@ -962,3 +962,8 @@
## Username for the Session. Default is your system username.
# Default: 'user'
# c.Session.username = 'user'
+
+# Truncate large collections (lists, dicts, tuples, sets) to this size.
+# Set to 0 to disable truncation.
+# Default: 1000
+c.PlainTextFormatter.max_seq_length = 0
diff --git a/template/jupyter-healthcheck.sh b/template/jupyter-healthcheck.sh
new file mode 100644
index 00000000..a4c00131
--- /dev/null
+++ b/template/jupyter-healthcheck.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+# Custom health check for Jupyter Server
+# Verifies the server is responsive via the /api/status endpoint
+
+MAX_RETRIES=50
+RETRY_INTERVAL=0.2
+
+for i in $(seq 1 $MAX_RETRIES); do
+ status_code=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:8888/api/status")
+
+ if [ "$status_code" -eq 200 ]; then
+ echo "Jupyter Server is healthy"
+ exit 0
+ fi
+
+ if [ $((i % 10)) -eq 0 ]; then
+ echo "Waiting for Jupyter Server to become healthy... (attempt $i/$MAX_RETRIES)"
+ fi
+ sleep $RETRY_INTERVAL
+done
+
+echo "Jupyter Server health check failed after $MAX_RETRIES attempts"
+exit 1
diff --git a/template/jupyter_server_config.py b/template/jupyter_server_config.py
index 379aa631..663682cc 100644
--- a/template/jupyter_server_config.py
+++ b/template/jupyter_server_config.py
@@ -3,6 +3,19 @@
c = get_config() # noqa
+# Pin the contents root directory.
+#
+# Sessions are created with a relative path (a bare uuid, see
+# server/contexts.py). Without an explicit root_dir, jupyter-server
+# inherits the process working directory as its root — which is "/"
+# under systemd (jupyter.service has no WorkingDirectory). Since
+# jupyter-server 2.18.0 (CVE-2026-35397 path-traversal hardening), a
+# root_dir of "/" makes every POST /api/sessions fail with
+# " is outside root contents directory", so the server never
+# starts. Pinning it to /home/user matches the execution cwd.
+c.ServerApp.root_dir = "/home/user"
+
+
# Set the Access-Control-Allow-Origin header
#
# Use '*' to allow any origin to access your server.
@@ -41,3 +54,11 @@
# with the full knowledge of what that implies.
# Default: False
c.ServerApp.disable_check_xsrf = True
+
+# Whether to allow the user to run the server as root.
+# Default: False
+c.ServerApp.allow_root = True
+
+# (bytes/sec) Maximum rate at which messages can be sent on iopub before they are limited.
+# Default: 1000000
+c.ServerApp.iopub_data_rate_limit = 1000000000
diff --git a/template/matplotlibrc b/template/matplotlibrc
new file mode 100644
index 00000000..b71d01f3
--- /dev/null
+++ b/template/matplotlibrc
@@ -0,0 +1 @@
+font.family: sans-serif, Noto Sans CJK JP
diff --git a/template/package.json b/template/package.json
new file mode 100644
index 00000000..ae911686
--- /dev/null
+++ b/template/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@e2b/code-interpreter-template",
+ "private": true,
+ "version": "0.4.3",
+ "scripts": {
+ "lint": "ruff check .",
+ "format": "ruff format ."
+ }
+}
diff --git a/template/requirements-dev.txt b/template/requirements-dev.txt
new file mode 100644
index 00000000..c9bb5e36
--- /dev/null
+++ b/template/requirements-dev.txt
@@ -0,0 +1,2 @@
+e2b==2.25.1
+python-dotenv==1.2.2
\ No newline at end of file
diff --git a/template/requirements.txt b/template/requirements.txt
index 01588ce5..71e7146b 100644
--- a/template/requirements.txt
+++ b/template/requirements.txt
@@ -1,36 +1,44 @@
# Jupyter server requirements
-jupyter-server==2.13.0
-ipykernel==6.29.3
-ipython==8.22.2
+jupyter-server==2.18.0
+ipykernel==6.31.0
+ipython==9.14.0
+
+orjson==3.11.9
+pandas==2.2.3
+matplotlib==3.10.9
+pillow==12.2.0
+
+# Latest version for
+e2b_charts
# Other packages
-aiohttp==3.9.3
-beautifulsoup4==4.12.3
-bokeh==3.3.4
-gensim==4.3.2
-imageio==2.34.0
-joblib==1.3.2
-librosa==0.10.1
-matplotlib==3.8.3
-nltk==3.8.1
-numpy==1.26.4
-opencv-python==4.9.0.80
-openpyxl==3.1.2
-pandas==1.5.3
-plotly==5.19.0
-pytest==8.1.0
-python-docx==1.1.0
-pytz==2024.1
-requests==2.26.0
-scikit-image==0.22.0
-scikit-learn==1.4.1.post1
-scipy==1.12.0
+aiohttp==3.14.0
+beautifulsoup4==4.14.3
+bokeh==3.9.0
+gensim==4.4.0
+imageio==2.37.3
+joblib==1.5.3
+librosa==0.11.0
+nltk==3.9.4
+numpy==2.3.5
+numba==0.63.1
+opencv-python==4.11.0.86
+openpyxl==3.1.5
+plotly==6.0.1
+kaleido==1.3.0
+pytest==9.0.3
+python-docx==1.1.2
+pytz==2025.2
+requests==2.33.0
+scikit-image==0.25.2
+scikit-learn==1.6.1
+scipy==1.17.1
seaborn==0.13.2
-soundfile==0.12.1
-spacy==3.7.4
-textblob==0.18.0
-tornado==6.4
-urllib3==1.26.7
-xarray==2024.2.0
-xlrd==2.0.1
-sympy==1.12
+soundfile==0.13.1
+spacy==3.8.14
+textblob==0.19.0
+tornado==6.5.6
+urllib3==2.7.0
+xarray==2025.4.0
+xlrd==2.0.2
+sympy==1.14.0
diff --git a/template/server/api/models/__init__.py b/template/server/api/models/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/template/server/api/models/context.py b/template/server/api/models/context.py
new file mode 100644
index 00000000..5efb850e
--- /dev/null
+++ b/template/server/api/models/context.py
@@ -0,0 +1,11 @@
+from pydantic import BaseModel, StrictStr
+from pydantic import Field
+
+
+class Context(BaseModel):
+ id: StrictStr = Field(description="Context ID")
+ language: StrictStr = Field(description="Language of the context")
+ cwd: StrictStr = Field(description="Current working directory of the context")
+
+ def __hash__(self):
+ return hash(self.id)
diff --git a/template/server/api/models/create_context.py b/template/server/api/models/create_context.py
new file mode 100644
index 00000000..1e1fefb7
--- /dev/null
+++ b/template/server/api/models/create_context.py
@@ -0,0 +1,13 @@
+from pydantic import BaseModel, StrictStr
+from pydantic import Field
+from typing import Optional
+
+
+class CreateContext(BaseModel):
+ cwd: Optional[StrictStr] = Field(
+ default="/home/user",
+ description="Current working directory",
+ )
+ language: Optional[StrictStr] = Field(
+ default="python", description="Language of the context"
+ )
diff --git a/template/server/api/models/env_vars.py b/template/server/api/models/env_vars.py
new file mode 100644
index 00000000..7c51bcca
--- /dev/null
+++ b/template/server/api/models/env_vars.py
@@ -0,0 +1,4 @@
+from typing import Dict
+from pydantic import StrictStr
+
+EnvVars = Dict[StrictStr, str]
diff --git a/template/server/api/models/error.py b/template/server/api/models/error.py
new file mode 100644
index 00000000..b17a6abc
--- /dev/null
+++ b/template/server/api/models/error.py
@@ -0,0 +1,17 @@
+from typing import Optional
+from pydantic import BaseModel, StrictStr
+from pydantic import Field
+
+from api.models.output import OutputType
+
+
+class Error(BaseModel):
+ type: OutputType = OutputType.ERROR
+
+ name: Optional[StrictStr] = Field(default=None, description="Name of the exception")
+ value: Optional[StrictStr] = Field(
+ default=None, description="Value of the exception"
+ )
+ traceback: Optional[StrictStr] = Field(
+ default=None, description="Traceback of the exception"
+ )
diff --git a/template/server/api/models/execution_request.py b/template/server/api/models/execution_request.py
new file mode 100644
index 00000000..bb691e9e
--- /dev/null
+++ b/template/server/api/models/execution_request.py
@@ -0,0 +1,16 @@
+from typing import Optional
+from pydantic import BaseModel, StrictStr
+from pydantic import Field
+
+from .env_vars import EnvVars
+
+
+class ExecutionRequest(BaseModel):
+ code: StrictStr = Field(description="Code to be executed")
+ context_id: Optional[StrictStr] = Field(default=None, description="Context ID")
+ language: Optional[StrictStr] = Field(
+ default=None, description="Language of the code"
+ )
+ env_vars: Optional[EnvVars] = Field(
+ description="Environment variables", default=None
+ )
diff --git a/template/server/api/models/logs.py b/template/server/api/models/logs.py
new file mode 100644
index 00000000..d9a433fe
--- /dev/null
+++ b/template/server/api/models/logs.py
@@ -0,0 +1,19 @@
+import datetime
+
+
+from typing import Optional
+from pydantic import BaseModel, StrictStr
+
+from api.models.output import OutputType
+
+
+class Stdout(BaseModel):
+ type: OutputType = OutputType.STDOUT
+ text: Optional[StrictStr] = None
+ timestamp: Optional[datetime.datetime] = None
+
+
+class Stderr(BaseModel):
+ type: OutputType = OutputType.STDERR
+ text: Optional[StrictStr] = None
+ timestamp: Optional[datetime.datetime] = None
diff --git a/template/server/api/models/output.py b/template/server/api/models/output.py
new file mode 100644
index 00000000..8e620c38
--- /dev/null
+++ b/template/server/api/models/output.py
@@ -0,0 +1,31 @@
+from __future__ import annotations
+
+from enum import Enum
+from pydantic import BaseModel
+
+
+class OutputType(Enum):
+ """
+ Represents the type of the data to send to the client.
+ """
+
+ STDOUT = "stdout"
+ STDERR = "stderr"
+ RESULT = "result"
+ ERROR = "error"
+ NUMBER_OF_EXECUTIONS = "number_of_executions"
+ END_OF_EXECUTION = "end_of_execution"
+ UNEXPECTED_END_OF_EXECUTION = "unexpected_end_of_execution"
+
+
+class EndOfExecution(BaseModel):
+ type: OutputType = OutputType.END_OF_EXECUTION
+
+
+class UnexpectedEndOfExecution(BaseModel):
+ type: OutputType = OutputType.UNEXPECTED_END_OF_EXECUTION
+
+
+class NumberOfExecutions(BaseModel):
+ type: OutputType = OutputType.NUMBER_OF_EXECUTIONS
+ execution_count: int
diff --git a/template/server/api/models/result.py b/template/server/api/models/result.py
new file mode 100644
index 00000000..90e24a9a
--- /dev/null
+++ b/template/server/api/models/result.py
@@ -0,0 +1,105 @@
+from __future__ import annotations
+
+import warnings
+
+from typing import Optional, Iterable
+from pydantic import BaseModel
+
+from api.models.output import OutputType
+
+warnings.filterwarnings("ignore", category=UserWarning)
+
+
+class Result(BaseModel):
+ """
+ Represents the data to be displayed as a result of executing a cell in a Jupyter notebook.
+ The result is similar to the structure returned by ipython kernel: https://ipython.readthedocs.io/en/stable/development/execution.html#execution-semantics
+
+ The result can contain multiple types of data, such as text, images, plots, etc. Each type of data is represented
+ as a string, and the result can contain multiple types of data. The display calls don't have to have text representation,
+ for the actual result the representation is always present for the result, the other representations are always optional.
+ """
+
+ type: OutputType = OutputType.RESULT
+
+ text: Optional[str] = None
+ html: Optional[str] = None
+ markdown: Optional[str] = None
+ svg: Optional[str] = None
+ png: Optional[str] = None
+ jpeg: Optional[str] = None
+ pdf: Optional[str] = None
+ latex: Optional[str] = None
+ json: Optional[dict] = None
+ javascript: Optional[str] = None
+ data: Optional[dict] = None
+ chart: Optional[dict] = None
+ extra: Optional[dict] = None
+ "Extra data that can be included. Not part of the standard types."
+
+ is_main_result: Optional[bool] = None
+ "Whether this data is the result of the execetution. Data can be produced by display calls of which can be multiple in a cell."
+
+ def __init__(self, is_main_result: bool, data: [str, str]):
+ super().__init__()
+ self.is_main_result = is_main_result
+
+ self.text = data.pop("text/plain", None)
+ if self.text and (
+ (self.text.startswith("'") and self.text.endswith("'"))
+ or (self.text.startswith('"') and self.text.endswith('"'))
+ ):
+ self.text = self.text[1:-1]
+
+ self.html = data.pop("text/html", None)
+ self.markdown = data.pop("text/markdown", None)
+ self.svg = data.pop("image/svg+xml", None)
+ self.png = data.pop("image/png", None)
+ self.jpeg = data.pop("image/jpeg", None)
+ self.pdf = data.pop("application/pdf", None)
+ self.latex = data.pop("text/latex", None)
+ self.json = data.pop("application/json", None)
+ self.javascript = data.pop("application/javascript", None)
+ self.data = data.pop("e2b/data", None)
+ self.chart = data.pop("e2b/chart", None)
+ self.extra = data
+
+ def formats(self) -> Iterable[str]:
+ formats = []
+
+ for key in [
+ "text",
+ "html",
+ "markdown",
+ "svg",
+ "png",
+ "jpeg",
+ "pdf",
+ "latex",
+ "json",
+ "javascript",
+ "data",
+ "chart",
+ ]:
+ if getattr(self, key):
+ formats.append(key)
+
+ if self.extra:
+ for key in self.extra:
+ formats.append(key)
+
+ return formats
+
+ def __str__(self) -> str:
+ """
+ Returns the text representation of the data.
+
+ :return: The text representation of the data.
+ """
+ return self.__repr__()
+
+ def __repr__(self) -> str:
+ if self.text:
+ return f"Result({self.text})"
+ formats = self.formats()
+ return f"Result with formats: {formats}"
diff --git a/template/server/consts.py b/template/server/consts.py
new file mode 100644
index 00000000..e1b92a06
--- /dev/null
+++ b/template/server/consts.py
@@ -0,0 +1 @@
+JUPYTER_BASE_URL = "http://localhost:8888"
diff --git a/template/server/contexts.py b/template/server/contexts.py
new file mode 100644
index 00000000..773f3fa8
--- /dev/null
+++ b/template/server/contexts.py
@@ -0,0 +1,72 @@
+import logging
+import uuid
+from typing import Optional
+
+from api.models.context import Context
+from fastapi.responses import PlainTextResponse
+
+from consts import JUPYTER_BASE_URL
+from errors import ExecutionError
+from messaging import ContextWebSocket
+
+logger = logging.Logger(__name__)
+
+
+def get_kernel_for_language(language: str) -> str:
+ if language == "typescript":
+ return "javascript"
+
+ return language
+
+
+def normalize_language(language: Optional[str]) -> str:
+ if not language:
+ return "python"
+
+ language = language.lower().strip()
+
+ if language == "js":
+ return "javascript"
+
+ if language == "ts":
+ return "typescript"
+
+ return language
+
+
+async def create_context(client, websockets: dict, language: str, cwd: str) -> Context:
+ data = {
+ "path": str(uuid.uuid4()),
+ "kernel": {"name": get_kernel_for_language(language)},
+ "type": "notebook",
+ "name": str(uuid.uuid4()),
+ }
+ logger.debug(f"Creating new {language} context")
+
+ response = await client.post(f"{JUPYTER_BASE_URL}/api/sessions", json=data)
+
+ if not response.is_success:
+ raise Exception(
+ f"Failed to create context: {response.text}",
+ )
+
+ session_data = response.json()
+ session_id = session_data["id"]
+ context_id = session_data["kernel"]["id"]
+
+ logger.debug(f"Created context {context_id}")
+
+ ws = ContextWebSocket(context_id, session_id, language, cwd)
+ await ws.connect()
+ websockets[context_id] = ws
+
+ logger.info(f"Setting working directory to {cwd}")
+ try:
+ await ws.change_current_directory(cwd, language)
+ except ExecutionError:
+ return PlainTextResponse(
+ "Failed to set working directory",
+ status_code=500,
+ )
+
+ return Context(language=language, id=context_id, cwd=cwd)
diff --git a/template/server/envs.py b/template/server/envs.py
new file mode 100644
index 00000000..8752e7b9
--- /dev/null
+++ b/template/server/envs.py
@@ -0,0 +1,20 @@
+import os
+from typing import Optional
+
+import httpx
+
+LOCAL = os.getenv("E2B_LOCAL", False)
+ENVD_PORT = 49983
+
+
+async def get_envs(access_token: Optional[str]) -> dict:
+ if LOCAL:
+ return {"E2B_TEST_VARIABLE": "true"}
+ async with httpx.AsyncClient() as client:
+ headers = {}
+ if access_token:
+ headers["X-Access-Token"] = f"{access_token}"
+ response = await client.get(
+ f"http://localhost:{ENVD_PORT}/envs", headers=headers
+ )
+ return response.json()
diff --git a/template/server/errors.py b/template/server/errors.py
new file mode 100644
index 00000000..ab4b43bc
--- /dev/null
+++ b/template/server/errors.py
@@ -0,0 +1,2 @@
+class ExecutionError(Exception):
+ pass
diff --git a/template/server/main.py b/template/server/main.py
new file mode 100644
index 00000000..59215f57
--- /dev/null
+++ b/template/server/main.py
@@ -0,0 +1,217 @@
+import logging
+import sys
+import httpx
+
+from typing import Dict, Union, Literal, List
+
+from contextlib import asynccontextmanager
+from fastapi import FastAPI, Request
+from fastapi.middleware.cors import CORSMiddleware
+from fastapi.responses import PlainTextResponse
+
+from api.models.context import Context
+from api.models.create_context import CreateContext
+from api.models.execution_request import ExecutionRequest
+from consts import JUPYTER_BASE_URL
+from contexts import create_context, normalize_language
+from messaging import ContextWebSocket
+from stream import StreamingListJsonResponse
+from utils.locks import LockedMap
+
+logging.basicConfig(level=logging.DEBUG, stream=sys.stdout)
+logger = logging.Logger(__name__)
+http_logger = logging.getLogger("httpcore.http11")
+http_logger.setLevel(logging.WARNING)
+
+
+websockets: Dict[Union[str, Literal["default"]], ContextWebSocket] = {}
+default_websockets = LockedMap()
+global client
+
+
+@asynccontextmanager
+async def lifespan(app: FastAPI):
+ global client
+ client = httpx.AsyncClient()
+
+ try:
+ python_context = await create_context(
+ client, websockets, "python", "/home/user"
+ )
+ default_websockets["python"] = python_context.id
+ websockets["default"] = websockets[python_context.id]
+
+ javascript_context = await create_context(
+ client, websockets, "javascript", "/home/user"
+ )
+ default_websockets["javascript"] = javascript_context.id
+
+ logger.info("Connected to default runtime")
+ yield
+
+ # Will cleanup after application shuts down
+ for ws in websockets.values():
+ await ws.close()
+
+ await client.aclose()
+ except Exception as e:
+ logger.error(f"Failed to initialize default context: {e}")
+ raise
+
+
+app = FastAPI(lifespan=lifespan)
+
+app.add_middleware(
+ CORSMiddleware,
+ allow_origins=["*"],
+ allow_methods=["*"],
+ allow_headers=["*"],
+)
+
+logger.info("Starting Code Interpreter server")
+
+
+@app.get("/health")
+async def get_health():
+ return "OK"
+
+
+@app.post("/execute")
+async def post_execute(request: Request, exec_request: ExecutionRequest):
+ logger.info(f"Executing code: {exec_request.code}")
+
+ if exec_request.context_id and exec_request.language:
+ return PlainTextResponse(
+ "Only one of context_id or language can be provided",
+ status_code=400,
+ )
+
+ context_id = None
+ if exec_request.language:
+ language = normalize_language(exec_request.language)
+
+ async with await default_websockets.get_lock(language):
+ context_id = default_websockets.get(language)
+
+ if not context_id:
+ try:
+ context = await create_context(
+ client, websockets, language, "/home/user"
+ )
+ except Exception as e:
+ return PlainTextResponse(str(e), status_code=500)
+
+ context_id = context.id
+ default_websockets[language] = context_id
+
+ elif exec_request.context_id:
+ context_id = exec_request.context_id
+
+ if context_id:
+ ws = websockets.get(context_id, None)
+ else:
+ ws = websockets["default"]
+
+ if not ws:
+ return PlainTextResponse(
+ f"Context {exec_request.context_id} not found",
+ status_code=404,
+ )
+
+ return StreamingListJsonResponse(
+ ws.execute(
+ exec_request.code,
+ env_vars=exec_request.env_vars,
+ access_token=request.headers.get("X-Access-Token", None),
+ )
+ )
+
+
+@app.post("/contexts")
+async def post_contexts(request: CreateContext) -> Context:
+ logger.info("Creating a new context")
+
+ language = normalize_language(request.language)
+ cwd = request.cwd or "/home/user"
+
+ try:
+ return await create_context(client, websockets, language, cwd)
+ except Exception as e:
+ return PlainTextResponse(str(e), status_code=500)
+
+
+@app.get("/contexts")
+async def get_contexts() -> List[Context]:
+ logger.info("Listing contexts")
+
+ return [
+ Context(
+ id=ws.context_id,
+ language=ws.language,
+ cwd=ws.cwd,
+ )
+ for key, ws in websockets.items()
+ if key != "default"
+ ]
+
+
+@app.post("/contexts/{context_id}/restart")
+async def restart_context(context_id: str) -> None:
+ logger.info(f"Restarting context {context_id}")
+
+ ws = websockets.get(context_id, None)
+ if not ws:
+ return PlainTextResponse(
+ f"Context {context_id} not found",
+ status_code=404,
+ )
+
+ session_id = ws.session_id
+
+ await ws.close()
+
+ response = await client.post(
+ f"{JUPYTER_BASE_URL}/api/kernels/{ws.context_id}/restart"
+ )
+ if not response.is_success:
+ return PlainTextResponse(
+ f"Failed to restart context {context_id}",
+ status_code=500,
+ )
+
+ ws = ContextWebSocket(
+ ws.context_id,
+ session_id,
+ ws.language,
+ ws.cwd,
+ )
+
+ await ws.connect()
+
+ websockets[context_id] = ws
+
+
+@app.delete("/contexts/{context_id}")
+async def remove_context(context_id: str) -> None:
+ logger.info(f"Removing context {context_id}")
+
+ ws = websockets.get(context_id, None)
+ if not ws:
+ return PlainTextResponse(
+ f"Context {context_id} not found",
+ status_code=404,
+ )
+
+ try:
+ await ws.close()
+ except: # noqa: E722
+ pass
+
+ response = await client.delete(f"{JUPYTER_BASE_URL}/api/kernels/{ws.context_id}")
+ if not response.is_success:
+ return PlainTextResponse(
+ f"Failed to remove context {context_id}",
+ status_code=500,
+ )
+
+ del websockets[context_id]
diff --git a/template/server/messaging.py b/template/server/messaging.py
new file mode 100644
index 00000000..c51f8b21
--- /dev/null
+++ b/template/server/messaging.py
@@ -0,0 +1,608 @@
+import datetime
+import json
+import logging
+import uuid
+import asyncio
+
+import httpx
+
+from asyncio import Queue
+from typing import (
+ Dict,
+ Optional,
+ Union,
+)
+from pydantic import StrictStr
+from websockets.client import WebSocketClientProtocol, connect
+from websockets.exceptions import (
+ ConnectionClosedError,
+ WebSocketException,
+)
+
+from api.models.error import Error
+from api.models.logs import Stdout, Stderr
+from api.models.result import Result
+from api.models.output import (
+ EndOfExecution,
+ NumberOfExecutions,
+ OutputType,
+ UnexpectedEndOfExecution,
+)
+from consts import JUPYTER_BASE_URL
+from errors import ExecutionError
+from envs import get_envs
+
+logger = logging.getLogger(__name__)
+
+MAX_RECONNECT_RETRIES = 3
+PING_TIMEOUT = 30
+KEEPALIVE_INTERVAL = 5 # seconds between keepalive pings during streaming
+
+
+class Execution:
+ def __init__(self, in_background: bool = False):
+ self.queue = Queue[
+ Union[
+ Result,
+ Error,
+ Stdout,
+ Stderr,
+ EndOfExecution,
+ NumberOfExecutions,
+ UnexpectedEndOfExecution,
+ ]
+ ]()
+ self.input_accepted = False
+ self.errored = False
+ self.in_background = in_background
+
+
+class ContextWebSocket:
+ _ws: Optional[WebSocketClientProtocol] = None
+ _receive_task: Optional[asyncio.Task] = None
+ _global_env_vars: Optional[Dict[StrictStr, str]] = None
+ _cleanup_task: Optional[asyncio.Task] = None
+
+ def __init__(self, context_id: str, session_id: str, language: str, cwd: str):
+ self.language = language
+ self.cwd = cwd
+ self.context_id = context_id
+ self.url = f"ws://localhost:8888/api/kernels/{context_id}/channels"
+ self.session_id = session_id
+ self._executions: Dict[str, Execution] = {}
+ self._lock = asyncio.Lock()
+
+ async def reconnect(self):
+ if self._ws is not None:
+ await self._ws.close(reason="Reconnecting")
+
+ if self._receive_task is not None:
+ await self._receive_task
+
+ await self.connect()
+
+ async def connect(self):
+ logger.debug(f"WebSocket connecting to {self.url}")
+
+ ws_logger = logger.getChild("websockets.client")
+ ws_logger.setLevel(logging.ERROR)
+
+ self._ws = await connect(
+ self.url,
+ ping_timeout=PING_TIMEOUT,
+ max_size=None,
+ max_queue=None,
+ logger=ws_logger,
+ )
+
+ logger.info(f"WebSocket connected to {self.url}")
+ self._receive_task = asyncio.create_task(
+ self._receive_message(),
+ name="receive_message",
+ )
+
+ async def interrupt(self):
+ """Interrupt the current kernel execution via the Jupyter REST API."""
+ try:
+ async with httpx.AsyncClient() as client:
+ response = await client.post(
+ f"{JUPYTER_BASE_URL}/api/kernels/{self.context_id}/interrupt"
+ )
+ if response.is_success:
+ logger.info(f"Kernel {self.context_id} interrupted successfully")
+ else:
+ logger.error(
+ f"Failed to interrupt kernel {self.context_id}: {response.status_code}"
+ )
+ except Exception as e:
+ logger.error(f"Error interrupting kernel {self.context_id}: {e}")
+
+ def _get_execute_request(
+ self, msg_id: str, code: Union[str, StrictStr], background: bool
+ ) -> str:
+ return json.dumps(
+ {
+ "header": {
+ "msg_id": msg_id,
+ "username": "e2b",
+ "session": self.session_id,
+ "msg_type": "execute_request",
+ "version": "5.3",
+ "date": datetime.datetime.now(datetime.timezone.utc).isoformat(),
+ },
+ "parent_header": {},
+ "metadata": {
+ "trusted": True,
+ "deletedCells": [],
+ "recordTiming": False,
+ "cellId": str(uuid.uuid4()),
+ },
+ "content": {
+ "code": code,
+ "silent": background,
+ "store_history": True,
+ "user_expressions": {},
+ "stop_on_error": True,
+ "allow_stdin": False,
+ },
+ }
+ )
+
+ def _set_env_var_snippet(self, key: str, value: str) -> str:
+ """Get environment variable set command for the current language."""
+ if self.language == "python":
+ return f"import os; os.environ['{key}'] = '{value}'"
+ elif self.language in ["javascript", "typescript"]:
+ return f"process.env['{key}'] = '{value}'"
+ elif self.language == "r":
+ return f'Sys.setenv({key} = "{value}")'
+ elif self.language == "java":
+ return f'System.setProperty("{key}", "{value}");'
+ elif self.language == "bash":
+ return f"export {key}='{value}'"
+ return ""
+
+ def _delete_env_var_snippet(self, key: str) -> str:
+ """Get environment variable delete command for the current language."""
+ if self.language == "python":
+ return f"import os; del os.environ['{key}']"
+ elif self.language in ["javascript", "typescript"]:
+ return f"delete process.env['{key}']"
+ elif self.language == "r":
+ return f"Sys.unsetenv('{key}')"
+ elif self.language == "java":
+ return f'System.clearProperty("{key}");'
+ elif self.language == "bash":
+ return f"unset {key}"
+ return ""
+
+ def _set_env_vars_code(self, env_vars: Dict[StrictStr, str]) -> str:
+ """Build environment variable code for the current language."""
+ env_commands = []
+ for k, v in env_vars.items():
+ command = self._set_env_var_snippet(k, v)
+ if command:
+ env_commands.append(command)
+
+ return "\n".join(env_commands)
+
+ def _reset_env_vars_code(self, env_vars: Dict[StrictStr, str]) -> str:
+ """Build environment variable cleanup code for the current language."""
+ cleanup_commands = []
+
+ for key in env_vars:
+ # Check if this var exists in global env vars
+ if self._global_env_vars and key in self._global_env_vars:
+ # Reset to global value
+ value = self._global_env_vars[key]
+ command = self._set_env_var_snippet(key, value)
+ else:
+ # Remove the variable
+ command = self._delete_env_var_snippet(key)
+
+ if command:
+ cleanup_commands.append(command)
+
+ return "\n".join(cleanup_commands)
+
+ def _get_code_indentation(self, code: str) -> str:
+ """Get the indentation from the first non-empty line of code."""
+ if not code or not code.strip():
+ return ""
+
+ lines = code.split("\n")
+ for line in lines:
+ if line.strip(): # First non-empty line
+ return line[: len(line) - len(line.lstrip())]
+
+ return ""
+
+ def _indent_code_with_level(self, code: str, indent_level: str) -> str:
+ """Apply the given indentation level to each line of code."""
+ if not code or not indent_level:
+ return code
+
+ lines = code.split("\n")
+ indented_lines = []
+
+ for line in lines:
+ if line.strip(): # Non-empty lines
+ indented_lines.append(indent_level + line)
+ else:
+ indented_lines.append(line)
+
+ return "\n".join(indented_lines)
+
+ async def _cleanup_env_vars(self, env_vars: Dict[StrictStr, str]):
+ """Clean up environment variables in a separate execution request."""
+ message_id = str(uuid.uuid4())
+ self._executions[message_id] = Execution(in_background=True)
+
+ try:
+ cleanup_code = self._reset_env_vars_code(env_vars)
+ if cleanup_code:
+ logger.info(f"Cleaning up env vars: {cleanup_code}")
+ request = self._get_execute_request(message_id, cleanup_code, True)
+ await self._ws.send(request)
+
+ async for item in self._wait_for_result(message_id):
+ if item["type"] == "error":
+ logger.error(f"Error during env var cleanup: {item}")
+ finally:
+ del self._executions[message_id]
+
+ async def _wait_for_result(self, message_id: str):
+ queue = self._executions[message_id].queue
+
+ # Use a timeout on queue.get() to periodically send keepalives.
+ # Without keepalives, the generator blocks indefinitely waiting for
+ # kernel output. If the client silently disappears (e.g. network
+ # failure), uvicorn can only detect the broken connection when it
+ # tries to write — so we force a write every KEEPALIVE_INTERVAL
+ # seconds. This ensures timely disconnect detection and kernel
+ # interrupt for abandoned executions (see #213).
+ while True:
+ try:
+ output = await asyncio.wait_for(queue.get(), timeout=KEEPALIVE_INTERVAL)
+ except asyncio.TimeoutError:
+ # Yield a keepalive so Starlette writes to the socket.
+ # If the client has disconnected, the write fails and
+ # uvicorn delivers http.disconnect, which cancels this
+ # generator via CancelledError.
+ yield {"type": "keepalive"}
+ continue
+
+ if output.type == OutputType.END_OF_EXECUTION:
+ break
+
+ if output.type == OutputType.UNEXPECTED_END_OF_EXECUTION:
+ logger.error(f"Unexpected end of execution for code ({message_id})")
+ yield Error(
+ name="UnexpectedEndOfExecution",
+ value="Connection to the execution was closed before the execution was finished",
+ traceback="",
+ )
+ break
+
+ yield output.model_dump(exclude_none=True)
+
+ async def change_current_directory(
+ self, path: Union[str, StrictStr], language: str
+ ):
+ message_id = str(uuid.uuid4())
+ self._executions[message_id] = Execution(in_background=True)
+ if language == "python":
+ request = self._get_execute_request(message_id, f"%cd {path}", True)
+ elif language in ("javascript", "typescript"):
+ request = self._get_execute_request(
+ message_id, f"process.chdir('{path}')", True
+ )
+ elif language == "r":
+ request = self._get_execute_request(message_id, f"setwd('{path}')", True)
+ # This does not actually change the working directory, but sets the user.dir property
+ elif language == "java":
+ request = self._get_execute_request(
+ message_id, f'System.setProperty("user.dir", "{path}");', True
+ )
+ elif language == "bash":
+ request = self._get_execute_request(message_id, f"cd '{path}'", True)
+ else:
+ return
+
+ await self._ws.send(request)
+
+ async for item in self._wait_for_result(message_id):
+ if item["type"] == "error":
+ raise ExecutionError(f"Error during execution: {item}")
+
+ async def execute(
+ self,
+ code: Union[str, StrictStr],
+ env_vars: Dict[StrictStr, str],
+ access_token: str,
+ ):
+ if self._ws is None:
+ raise Exception("WebSocket not connected")
+
+ async with self._lock:
+ # Wait for any pending cleanup task to complete
+ if self._cleanup_task and not self._cleanup_task.done():
+ logger.debug("Waiting for pending cleanup task to complete")
+ try:
+ await self._cleanup_task
+ except Exception as e:
+ logger.warning(f"Cleanup task failed: {e}")
+ finally:
+ self._cleanup_task = None
+
+ # Get the indentation level from the code
+ code_indent = self._get_code_indentation(code)
+
+ # Build the complete code snippet with env vars
+ complete_code = code
+
+ global_env_vars_snippet = ""
+ env_vars_snippet = ""
+
+ if self._global_env_vars is None:
+ self._global_env_vars = await get_envs(access_token=access_token)
+ global_env_vars_snippet = self._set_env_vars_code(self._global_env_vars)
+
+ if env_vars:
+ env_vars_snippet = self._set_env_vars_code(env_vars)
+
+ if global_env_vars_snippet or env_vars_snippet:
+ indented_env_code = self._indent_code_with_level(
+ f"{global_env_vars_snippet}\n{env_vars_snippet}", code_indent
+ )
+ complete_code = f"{indented_env_code}\n{complete_code}"
+
+ message_id = str(uuid.uuid4())
+ execution = Execution()
+ self._executions[message_id] = execution
+
+ # Send the code for execution
+ # Initial request and retries
+ for i in range(1 + MAX_RECONNECT_RETRIES):
+ try:
+ logger.info(
+ f"Sending code for the execution ({message_id}): {complete_code}"
+ )
+ request = self._get_execute_request(
+ message_id, complete_code, False
+ )
+ await self._ws.send(request)
+ break
+ except (ConnectionClosedError, WebSocketException) as e:
+ # Keep the last result, even if error
+ if i < MAX_RECONNECT_RETRIES:
+ logger.warning(
+ f"WebSocket connection lost while sending execution request, {i + 1}. reconnecting...: {str(e)}"
+ )
+ await self.reconnect()
+ else:
+ # The retry didn't help, request wasn't sent successfully
+ logger.error("Failed to send execution request")
+ await execution.queue.put(
+ Error(
+ name="WebSocketError",
+ value="Failed to send execution request",
+ traceback="",
+ )
+ )
+ await execution.queue.put(UnexpectedEndOfExecution())
+
+ # Stream the results.
+ # If the client disconnects (Starlette cancels the task), we
+ # interrupt the kernel so the next execution isn't blocked (#213).
+ try:
+ async for item in self._wait_for_result(message_id):
+ yield item
+ except (asyncio.CancelledError, GeneratorExit):
+ logger.warning(
+ f"Client disconnected during execution ({message_id}), interrupting kernel"
+ )
+ # Shield the interrupt from the ongoing cancellation so
+ # the HTTP request to the kernel actually completes.
+ try:
+ await asyncio.shield(self.interrupt())
+ except asyncio.CancelledError:
+ pass
+ raise
+ finally:
+ if message_id in self._executions:
+ del self._executions[message_id]
+
+ # Clean up env vars in a separate request after the main code has run
+ if env_vars:
+ self._cleanup_task = asyncio.create_task(
+ self._cleanup_env_vars(env_vars)
+ )
+
+ async def _receive_message(self):
+ if not self._ws:
+ logger.error("No WebSocket connection")
+ return
+
+ try:
+ async for message in self._ws:
+ await self._process_message(json.loads(message))
+ except Exception as e:
+ logger.error(f"WebSocket received error while receiving messages: {str(e)}")
+ finally:
+ # To prevent infinite hang, we need to cancel all ongoing execution as we could lost results during the reconnect
+ # Thanks to the locking, there can be either no ongoing execution or just one.
+ for key, execution in self._executions.items():
+ await execution.queue.put(
+ Error(
+ name="WebSocketError",
+ value="The connections was lost, rerun the code to get the results",
+ traceback="",
+ )
+ )
+ await execution.queue.put(UnexpectedEndOfExecution())
+
+ async def _process_message(self, data: dict):
+ """
+ Process messages from the WebSocket
+
+ Message types:
+ https://jupyter-client.readthedocs.io/en/stable/messaging.html
+
+ :param data: The message data
+ """
+ if (
+ data["msg_type"] == "status"
+ and data["content"]["execution_state"] == "restarting"
+ ):
+ logger.error("Context is restarting")
+ for execution in self._executions.values():
+ await execution.queue.put(
+ Error(
+ name="ContextRestarting",
+ value="Context was restarted",
+ traceback="",
+ )
+ )
+ await execution.queue.put(EndOfExecution())
+ return
+
+ parent_msg_ig = data["parent_header"].get("msg_id", None)
+ if parent_msg_ig is None:
+ logger.warning("Parent message ID not found. %s", data)
+ return
+
+ execution = self._executions.get(parent_msg_ig)
+ if not execution:
+ return
+
+ queue = execution.queue
+ if data["msg_type"] == "error":
+ logger.debug(
+ f"Execution {parent_msg_ig} finished execution with error: {data['content']['ename']}: {data['content']['evalue']}"
+ )
+
+ if execution.errored:
+ return
+
+ execution.errored = True
+ await queue.put(
+ Error(
+ name=data["content"]["ename"],
+ value=data["content"]["evalue"],
+ traceback="".join(data["content"]["traceback"]),
+ )
+ )
+
+ elif data["msg_type"] == "stream":
+ if data["content"]["name"] == "stdout":
+ logger.debug(
+ f"Execution {parent_msg_ig} received stdout: {data['content']['text']}"
+ )
+ await queue.put(
+ Stdout(
+ text=data["content"]["text"], timestamp=data["header"]["date"]
+ )
+ )
+
+ elif data["content"]["name"] == "stderr":
+ logger.debug(
+ f"Execution {parent_msg_ig} received stderr: {data['content']['text']}"
+ )
+ await queue.put(
+ Stderr(
+ text=data["content"]["text"], timestamp=data["header"]["date"]
+ )
+ )
+
+ elif data["msg_type"] in "display_data":
+ result = Result(is_main_result=False, data=data["content"]["data"])
+ logger.debug(
+ f"Execution {parent_msg_ig} received display data with following formats: {result.formats()}"
+ )
+ await queue.put(result)
+
+ elif data["msg_type"] == "execute_result":
+ result = Result(is_main_result=True, data=data["content"]["data"])
+ logger.debug(
+ f"Execution {parent_msg_ig} received execution result with following formats: {result.formats()}"
+ )
+ await queue.put(result)
+
+ elif data["msg_type"] == "status":
+ if data["content"]["execution_state"] == "busy" and execution.in_background:
+ logger.debug(f"Execution {parent_msg_ig} started execution")
+ execution.input_accepted = True
+
+ if data["content"]["execution_state"] == "idle":
+ if execution.input_accepted:
+ logger.debug(f"Execution {parent_msg_ig} finished execution")
+ await queue.put(EndOfExecution())
+
+ elif data["content"]["execution_state"] == "error":
+ logger.debug(f"Execution {parent_msg_ig} finished execution with error")
+ await queue.put(
+ Error(
+ name=data["content"]["ename"],
+ value=data["content"]["evalue"],
+ traceback="".join(data["content"]["traceback"]),
+ )
+ )
+ await queue.put(EndOfExecution())
+
+ elif data["msg_type"] == "execute_reply":
+ if data["content"]["status"] == "error":
+ logger.debug(f"Execution {parent_msg_ig} finished execution with error")
+
+ if execution.errored:
+ return
+
+ execution.errored = True
+ await queue.put(
+ Error(
+ name=data["content"].get("ename", ""),
+ value=data["content"].get("evalue", ""),
+ traceback="".join(data["content"].get("traceback", [])),
+ )
+ )
+ elif data["content"]["status"] == "abort":
+ logger.debug(f"Execution {parent_msg_ig} was aborted")
+ await queue.put(
+ Error(
+ name="ExecutionAborted",
+ value="Execution was aborted",
+ traceback="",
+ )
+ )
+ await queue.put(EndOfExecution())
+ elif data["content"]["status"] == "ok":
+ pass
+
+ elif data["msg_type"] == "execute_input":
+ logger.debug(f"Input accepted for {parent_msg_ig}")
+ await queue.put(
+ NumberOfExecutions(execution_count=data["content"]["execution_count"])
+ )
+ execution.input_accepted = True
+ else:
+ logger.warning(f"[UNHANDLED MESSAGE TYPE]: {data['msg_type']}")
+
+ async def close(self):
+ logger.debug(f"Closing WebSocket {self.context_id}")
+
+ if self._ws is not None:
+ await self._ws.close()
+
+ if self._receive_task is not None:
+ self._receive_task.cancel()
+
+ # Cancel any pending cleanup task
+ if self._cleanup_task and not self._cleanup_task.done():
+ self._cleanup_task.cancel()
+ try:
+ await self._cleanup_task
+ except asyncio.CancelledError:
+ pass
+
+ for execution in self._executions.values():
+ execution.queue.put_nowait(UnexpectedEndOfExecution())
diff --git a/template/server/requirements.txt b/template/server/requirements.txt
new file mode 100644
index 00000000..b3e44b71
--- /dev/null
+++ b/template/server/requirements.txt
@@ -0,0 +1,6 @@
+fastapi==0.111.0
+httpx==0.28.1
+websockets==12.0
+uvicorn[standard]==0.30.1
+requests==2.33.0
+pydantic==2.9.1
diff --git a/template/server/stream.py b/template/server/stream.py
new file mode 100644
index 00000000..0ef0195b
--- /dev/null
+++ b/template/server/stream.py
@@ -0,0 +1,40 @@
+import json
+from typing import Mapping, Optional, AsyncIterable
+
+from fastapi.encoders import jsonable_encoder
+from starlette.background import BackgroundTask
+from fastapi.responses import StreamingResponse
+
+
+class StreamingListJsonResponse(StreamingResponse):
+ """Converts a pydantic model generator into a streaming HTTP Response
+ that streams a JSON list, one element at a time.
+
+ See https://github.com/tiangolo/fastapi/issues/1978
+ """
+
+ def __init__(
+ self,
+ content_generator: AsyncIterable,
+ status_code: int = 200,
+ headers: Optional[Mapping[str, str]] = None,
+ media_type: Optional[str] = None,
+ background: Optional[BackgroundTask] = None,
+ ) -> None:
+ body_iterator = self._encoded_async_generator(content_generator)
+
+ super().__init__(
+ content=body_iterator,
+ status_code=status_code,
+ headers=headers,
+ media_type=media_type,
+ background=background,
+ )
+
+ async def _encoded_async_generator(self, async_generator: AsyncIterable):
+ """Converts an asynchronous pydantic model generator
+ into a streaming JSON list
+ """
+ async for item in async_generator:
+ yield f"{json.dumps(jsonable_encoder(item))}\n"
+ yield '{"type": "end_of_execution"}\n'
diff --git a/template/server/utils/locks.py b/template/server/utils/locks.py
new file mode 100644
index 00000000..f4a5c6ea
--- /dev/null
+++ b/template/server/utils/locks.py
@@ -0,0 +1,18 @@
+import asyncio
+
+
+class LockedMap(dict):
+ def __init__(self):
+ super().__init__()
+ self._map_lock = asyncio.Lock()
+ self._locks = {}
+
+ async def get_lock(self, key):
+ await self._map_lock.acquire()
+ if key not in self._locks:
+ self._locks[key] = asyncio.Lock()
+
+ lock = self._locks[key]
+ print(f"Lock acquired for {key}")
+ self._map_lock.release()
+ return lock
diff --git a/template/start-up.sh b/template/start-up.sh
old mode 100644
new mode 100755
index 7a98ff6b..5786b039
--- a/template/start-up.sh
+++ b/template/start-up.sh
@@ -1,29 +1,16 @@
#!/bin/bash
-function start_jupyter_server() {
- response=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:8888/api")
- while [[ ${response} -ne 200 ]]; do
- echo "Waiting for Jupyter Server to start..."
- response=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:8888/api")
- done
- echo "Jupyter Server started"
-
- response=$(curl -s -X POST "localhost:8888/api/kernels" -H "Content-Type: application/json" -d '{"path": "/home/user"}')
- status=$(echo "${response}" | jq -r '.execution_state')
- if [[ ${status} != "starting" ]]; then
- echo "Error creating kernel: ${response} ${status}"
+function start_code_interpreter() {
+ /root/.jupyter/jupyter-healthcheck.sh
+ if [ $? -ne 0 ]; then
+ echo "Jupyter Server failed to start, aborting."
exit 1
fi
- echo "Kernel created"
-
- kernel=$(echo "${response}" | jq -r '.id')
-
- sudo mkdir -p /root/.jupyter
- sudo echo "${kernel}" | sudo tee /root/.jupyter/kernel_id >/dev/null
- echo "Jupyter Server started"
+ cd /root/.server/
+ .venv/bin/uvicorn main:app --host 0.0.0.0 --port 49999 --workers 1 --no-access-log --no-use-colors --timeout-keep-alive 640
}
-echo "Starting Jupyter Server..."
-start_jupyter_server &
-jupyter server --IdentityProvider.token=""
+echo "Starting Code Interpreter server..."
+start_code_interpreter &
+MATPLOTLIBRC=/root/.config/matplotlib/.matplotlibrc jupyter server --IdentityProvider.token="" >/dev/null 2>&1
diff --git a/template/startup_scripts/0002_data.py b/template/startup_scripts/0002_data.py
new file mode 100644
index 00000000..3e994487
--- /dev/null
+++ b/template/startup_scripts/0002_data.py
@@ -0,0 +1,85 @@
+import sys
+
+import IPython
+from IPython.core.formatters import BaseFormatter, JSONFormatter
+from traitlets.traitlets import Unicode, ObjectName
+
+
+class E2BDataFormatter(BaseFormatter):
+ format_type = Unicode("e2b/data")
+
+ print_method = ObjectName("_repr_e2b_data_")
+ _return_type = (dict, str)
+
+ def __call__(self, obj):
+ # IPython invokes every registered formatter for every displayed
+ # object. Gate on sys.modules so a non-DataFrame output (e.g. an
+ # int from `1 + 1`) doesn't pay the pandas import cost — a
+ # pandas.DataFrame can only exist if the user already imported
+ # pandas.
+ pandas = sys.modules.get("pandas")
+ if pandas is None or not isinstance(obj, pandas.DataFrame):
+ return super().__call__(obj)
+
+ result = obj.to_dict(orient="list")
+ for key, value in result.items():
+ # Check each column's values
+ result[key] = [
+ v.isoformat() if isinstance(v, pandas.Timestamp) else v for v in value
+ ]
+ return result
+
+
+class E2BChartFormatter(BaseFormatter):
+ format_type = Unicode("e2b/chart")
+
+ print_method = ObjectName("_repr_e2b_chart_")
+ _return_type = (dict, str)
+
+ def __call__(self, obj):
+ # Same sys.modules gate as E2BDataFormatter: a matplotlib Figure
+ # can only exist if the user already imported matplotlib.
+ if sys.modules.get("matplotlib") is None:
+ return super().__call__(obj)
+
+ from matplotlib.pyplot import Figure
+
+ if not isinstance(obj, Figure):
+ return super().__call__(obj)
+
+ from e2b_charts import chart_figure_to_dict
+
+ try:
+ return chart_figure_to_dict(obj)
+ except: # noqa: E722
+ return {}
+
+
+class E2BJSONFormatter(JSONFormatter):
+ def __call__(self, obj):
+ if isinstance(obj, (list, dict)):
+ try:
+ import orjson
+
+ return orjson.loads(
+ orjson.dumps(
+ obj, option=orjson.OPT_SERIALIZE_NUMPY | orjson.OPT_NON_STR_KEYS
+ )
+ ), {"expanded": True}
+ except TypeError:
+ pass
+
+ return super().__call__(obj)
+
+
+ip = IPython.get_ipython()
+ip.display_formatter.formatters["e2b/data"] = E2BDataFormatter(
+ parent=ip.display_formatter
+)
+ip.display_formatter.formatters["e2b/chart"] = E2BChartFormatter(
+ parent=ip.display_formatter
+)
+
+ip.display_formatter.formatters["application/json"] = E2BJSONFormatter(
+ parent=ip.display_formatter
+)
diff --git a/template/startup_scripts/0003_images.py b/template/startup_scripts/0003_images.py
new file mode 100644
index 00000000..4732d77d
--- /dev/null
+++ b/template/startup_scripts/0003_images.py
@@ -0,0 +1,24 @@
+from typing import Any
+
+from IPython.core.display_functions import display
+from PIL.Image import Image
+from PIL.ImageShow import UnixViewer
+
+
+def show_file(self, path: str, **options: Any) -> int:
+ # To prevent errors from trying to display image without any display
+ return 0
+
+
+UnixViewer.show_file = show_file
+original_save = Image.save
+
+
+def save(image, fp, format=None, **options):
+ if isinstance(fp, str):
+ display(image)
+
+ original_save(image, fp, format, **options)
+
+
+Image.save = save
diff --git a/template/systemd/code-interpreter.service b/template/systemd/code-interpreter.service
new file mode 100644
index 00000000..04c165b4
--- /dev/null
+++ b/template/systemd/code-interpreter.service
@@ -0,0 +1,17 @@
+[Unit]
+Description=Code Interpreter Server
+Documentation=https://github.com/e2b-dev/code-interpreter
+Requires=jupyter.service
+After=jupyter.service
+PartOf=jupyter.service
+StartLimitBurst=0
+
+[Service]
+Type=simple
+WorkingDirectory=/root/.server
+ExecStartPre=/root/.jupyter/jupyter-healthcheck.sh
+ExecStart=/root/.server/.venv/bin/uvicorn main:app --host 0.0.0.0 --port 49999 --workers 1 --no-access-log --no-use-colors --timeout-keep-alive 640
+Restart=on-failure
+RestartSec=1
+StandardOutput=journal
+StandardError=journal
diff --git a/template/systemd/jupyter-debug.conf b/template/systemd/jupyter-debug.conf
new file mode 100644
index 00000000..89377a6f
--- /dev/null
+++ b/template/systemd/jupyter-debug.conf
@@ -0,0 +1,5 @@
+# Debug-only drop-in: route Jupyter's stdout to the journal (the base unit
+# sends it to /dev/null) so ServerApp request/error logs are visible via
+# `journalctl -u jupyter`. Applied only by `make_template(debug=True)`.
+[Service]
+StandardOutput=journal
diff --git a/template/systemd/jupyter.service b/template/systemd/jupyter.service
new file mode 100644
index 00000000..37b83f29
--- /dev/null
+++ b/template/systemd/jupyter.service
@@ -0,0 +1,15 @@
+[Unit]
+Description=Jupyter Server
+Documentation=https://jupyter-server.readthedocs.io
+Wants=code-interpreter.service
+StartLimitBurst=0
+
+[Service]
+Type=simple
+Environment=MATPLOTLIBRC=/root/.config/matplotlib/.matplotlibrc
+ExecStart=/usr/local/bin/jupyter server --IdentityProvider.token=""
+ExecStartPost=-/usr/bin/systemctl reset-failed code-interpreter
+Restart=on-failure
+RestartSec=1
+StandardOutput=null
+StandardError=journal
diff --git a/template/template.py b/template/template.py
new file mode 100644
index 00000000..fd8dd937
--- /dev/null
+++ b/template/template.py
@@ -0,0 +1,146 @@
+from e2b import ReadyCmd, Template, wait_for_url
+
+
+def make_template(
+ kernels: list[str] = ["python", "r", "javascript", "bash", "java"],
+ is_docker: bool = False,
+ ready: ReadyCmd | None = None,
+ debug: bool = False,
+):
+ enabled_kernels = set(["python", "javascript"] + kernels)
+ # Start with base template
+ template = (
+ Template()
+ .from_image("python:3.13")
+ .set_user("root")
+ .set_workdir("/root")
+ .set_envs(
+ {
+ "PIP_DEFAULT_TIMEOUT": "100",
+ "PIP_DISABLE_PIP_VERSION_CHECK": "1",
+ "PIP_NO_CACHE_DIR": "1",
+ "JAVA_VERSION": "11",
+ "JAVA_HOME": "/usr/lib/jvm/jdk-${JAVA_VERSION}",
+ "IJAVA_VERSION": "1.3.0",
+ "R_VERSION": "4.5.*",
+ }
+ )
+ .apt_install(
+ [
+ "build-essential",
+ "curl",
+ "git",
+ "util-linux",
+ "jq",
+ "sudo",
+ "fonts-noto-cjk",
+ "ca-certificates",
+ ]
+ )
+ .run_cmd("curl -fsSL https://deb.nodesource.com/setup_20.x | bash -")
+ .apt_install("nodejs")
+ .copy("requirements.txt", "requirements.txt")
+ .pip_install("--no-cache-dir -r requirements.txt")
+ )
+
+ if "python" in enabled_kernels:
+ template = template.run_cmd("ipython kernel install --name 'python3' --user")
+
+ # Install R Kernel if requested
+ if "r" in enabled_kernels:
+ template = template.apt_install("r-base=${R_VERSION} r-base-dev").run_cmd(
+ [
+ "R -e \"install.packages('IRkernel', repos='https://cloud.r-project.org')\"",
+ "R -e \"IRkernel::installspec(user = FALSE, name = 'r', displayname = 'R')\"",
+ ]
+ )
+
+ # Install JavaScript Kernel if requested
+ if "javascript" in enabled_kernels:
+ template = template.npm_install(
+ "--unsafe-perm git+https://github.com/e2b-dev/ijavascript.git",
+ g=True,
+ ).run_cmd("ijsinstall --install=global")
+
+ # Install Bash Kernel if requested
+ if "bash" in enabled_kernels:
+ template = template.pip_install("bash_kernel").run_cmd(
+ "python -m bash_kernel.install"
+ )
+
+ # Install Java and Java Kernel if requested
+ if "java" in enabled_kernels:
+ template = template.run_cmd(
+ [
+ "mkdir -p /usr/lib/jvm",
+ "curl -fsSL https://download.java.net/java/ga/jdk${JAVA_VERSION}/openjdk-${JAVA_VERSION}_linux-x64_bin.tar.gz | tar -xz -C /usr/lib/jvm",
+ "update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk-${JAVA_VERSION}/bin/java 1",
+ "update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/jdk-${JAVA_VERSION}/bin/javac 1",
+ "wget https://github.com/SpencerPark/IJava/releases/download/v${IJAVA_VERSION}/ijava-${IJAVA_VERSION}.zip",
+ "unzip ijava-${IJAVA_VERSION}.zip",
+ "python install.py --sys-prefix",
+ ]
+ )
+
+ # Common setup steps (always run)
+ template = (
+ template
+ # Create server virtual environment
+ .copy("server", ".server")
+ .run_cmd("python -m venv .server/.venv")
+ # Copy and install server requirements
+ .run_cmd(
+ ".server/.venv/bin/pip install --no-cache-dir -r .server/requirements.txt"
+ )
+ )
+
+ # Copy configuration files
+ template = (
+ template.copy("matplotlibrc", ".config/matplotlib/.matplotlibrc")
+ .copy("jupyter-healthcheck.sh", ".jupyter/jupyter-healthcheck.sh")
+ .run_cmd("chmod +x .jupyter/jupyter-healthcheck.sh")
+ .copy("jupyter_server_config.py", ".jupyter/")
+ .make_dir(".ipython/profile_default/startup")
+ .copy("ipython_kernel_config.py", ".ipython/profile_default/")
+ .copy("startup_scripts", ".ipython/profile_default/startup")
+ )
+
+ if not is_docker:
+ template = template.copy(
+ "systemd/jupyter.service", "/etc/systemd/system/jupyter.service"
+ ).copy(
+ "systemd/code-interpreter.service",
+ "/etc/systemd/system/code-interpreter.service",
+ )
+ if debug:
+ # Drop-in that routes Jupyter's stdout to the journal for debugging.
+ template = template.copy(
+ "systemd/jupyter-debug.conf",
+ "/etc/systemd/system/jupyter.service.d/debug.conf",
+ )
+ else:
+ template = template.copy("start-up.sh", ".jupyter/start-up.sh").run_cmd(
+ "chmod +x .jupyter/start-up.sh"
+ )
+
+ if is_docker:
+ # create user user and /home/user
+ template = template.run_cmd("useradd -m user")
+ template = template.run_cmd("mkdir -p /home/user")
+ template = template.run_cmd("chown -R user:user /home/user")
+ # add to sudoers
+ template = template.run_cmd(
+ "echo 'user ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers"
+ )
+
+ template = template.set_user("user").set_workdir("/home/user")
+
+ if is_docker:
+ start_cmd = "sudo --preserve-env=E2B_LOCAL /root/.jupyter/start-up.sh"
+ else:
+ start_cmd = "sudo systemctl start jupyter"
+
+ if ready is None:
+ ready = wait_for_url("http://localhost:49999/health")
+
+ return template.set_start_cmd(start_cmd, ready)